unipdf/model/optimize/optimize.go
2020-09-14 09:32:45 +00:00

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 (_a "bytes";_df "crypto/md5";_cc "errors";_e "fmt";_fe "github.com/unidoc/unipdf/v3/common";_ee "github.com/unidoc/unipdf/v3/contentstream";_g "github.com/unidoc/unipdf/v3/core";_fc "github.com/unidoc/unipdf/v3/extractor";_b "github.com/unidoc/unipdf/v3/internal/textencoding";_ec "github.com/unidoc/unipdf/v3/model";_dfa "github.com/unidoc/unitype";_c "golang.org/x/image/draw";_d "image";_fg "math";);
// Optimize optimizes PDF objects to decrease PDF size.
func (_ga *Chain )Optimize (objects []_g .PdfObject )(_gg []_g .PdfObject ,_ca error ){_gg =objects ;for _ ,_dd :=range _ga ._af {_gg ,_ca =_dd .Optimize (_gg );if _ca !=nil {return _gg ,_ca ;};};return _gg ,nil ;};
// Optimize optimizes PDF objects to decrease PDF size.
func (_bgb *ObjectStreams )Optimize (objects []_g .PdfObject )(_fcc []_g .PdfObject ,_dab error ){_fbc :=&_g .PdfObjectStreams {};_abab :=make ([]_g .PdfObject ,0,len (objects ));for _ ,_dfef :=range objects {if _gfee ,_dbbg :=_dfef .(*_g .PdfIndirectObject );_dbbg &&_gfee .GenerationNumber ==0{_fbc .Append (_dfef );}else {_abab =append (_abab ,_dfef );};};if _fbc .Len ()==0{return _abab ,nil ;};_fcc =make ([]_g .PdfObject ,0,len (_abab )+_fbc .Len ()+1);if _fbc .Len ()> 1{_fcc =append (_fcc ,_fbc );};_fcc =append (_fcc ,_fbc .Elements ()...);_fcc =append (_fcc ,_abab ...);return _fcc ,nil ;};func _dfc (_ddg []_g .PdfObject )(_aa map[*_g .PdfObjectStream ]struct{},_cgg error ){_aa =map[*_g .PdfObjectStream ]struct{}{};_aae :=map[*_ec .PdfFont ]struct{}{};_cbe :=_ggec (_ddg );for _ ,_afe :=range _cbe ._dcc {_aaeg ,_gda :=_g .GetDict (_afe .PdfObject );if !_gda {continue ;};_eag ,_gda :=_g .GetDict (_aaeg .Get ("\u0052e\u0073\u006f\u0075\u0072\u0063\u0065s"));if !_gda {continue ;};_gb ,_ :=_egcf (_aaeg .Get ("\u0043\u006f\u006e\u0074\u0065\u006e\u0074\u0073"));_cgc ,_ccce :=_ec .NewPdfPageResourcesFromDict (_eag );if _ccce !=nil {return nil ,_ccce ;};_ed :=[]content {{_bga :_gb ,_ggg :_cgc }};_be :=_ceb (_aaeg .Get ("\u0041\u006e\u006e\u006f\u0074\u0073"));if _be !=nil {_ed =append (_ed ,_be ...);};for _ ,_bbd :=range _ed {_ff ,_ffc :=_fc .NewFromContents (_bbd ._bga ,_bbd ._ggg );if _ffc !=nil {return nil ,_ffc ;};_deb ,_ ,_ ,_ffc :=_ff .ExtractPageText ();if _ffc !=nil {return nil ,_ffc ;};for _ ,_ac :=range _deb .Marks ().Elements (){if _ac .Font ==nil {continue ;};if _ ,_acg :=_aae [_ac .Font ];!_acg {_aae [_ac .Font ]=struct{}{};};};};};_deg :=map[*_g .PdfObjectStream ][]*_ec .PdfFont {};for _ccf :=range _aae {_cggd :=_ccf .FontDescriptor ();if _cggd ==nil ||_cggd .FontFile2 ==nil {continue ;};_aab ,_aag :=_g .GetStream (_cggd .FontFile2 );if !_aag {continue ;};_deg [_aab ]=append (_deg [_aab ],_ccf );};for _fff :=range _deg {var _edb []rune ;var _eef []_dfa .GlyphIndex ;for _ ,_bea :=range _deg [_fff ]{switch _eefb :=_bea .Encoder ().(type ){case *_b .IdentityEncoder :_afg :=_eefb .RegisteredRunes ();_bba :=make ([]_dfa .GlyphIndex ,len (_afg ));for _fgb ,_aaga :=range _afg {_bba [_fgb ]=_dfa .GlyphIndex (_aaga );};_eef =append (_eef ,_bba ...);case *_b .TrueTypeFontEncoder :_cca :=_eefb .RegisteredRunes ();_edb =append (_edb ,_cca ...);case _b .SimpleEncoder :_bcg :=_eefb .Charcodes ();for _ ,_bfg :=range _bcg {_eba ,_bbb :=_eefb .CharcodeToRune (_bfg );if !_bbb {_fe .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",_bfg );continue ;};_edb =append (_edb ,_eba );};};};_cgg =_bg (_fff ,_edb ,_eef );if _cgg !=nil {_fe .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",_cgg );return nil ,_cgg ;};_aa [_fff ]=struct{}{};};return _aa ,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 _dafa (_bcga []_g .PdfObject ,_ddcc map[_g .PdfObject ]_g .PdfObject ){if _ddcc ==nil ||len (_ddcc )==0{return ;};for _gdgg ,_bcb :=range _bcga {if _ceg ,_dgag :=_ddcc [_bcb ];_dgag {_bcga [_gdgg ]=_ceg ;continue ;};_ddcc [_bcb ]=_bcb ;switch _dfea :=_bcb .(type ){case *_g .PdfObjectArray :_aagae :=make ([]_g .PdfObject ,_dfea .Len ());copy (_aagae ,_dfea .Elements ());_dafa (_aagae ,_ddcc );for _gbbc ,_dbfc :=range _aagae {_dfea .Set (_gbbc ,_dbfc );};case *_g .PdfObjectStreams :_dafa (_dfea .Elements (),_ddcc );case *_g .PdfObjectStream :_fee :=[]_g .PdfObject {_dfea .PdfObjectDictionary };_dafa (_fee ,_ddcc );_dfea .PdfObjectDictionary =_fee [0].(*_g .PdfObjectDictionary );case *_g .PdfObjectDictionary :_dde :=_dfea .Keys ();_fbed :=make ([]_g .PdfObject ,len (_dde ));for _bfd ,_ecac :=range _dde {_fbed [_bfd ]=_dfea .Get (_ecac );};_dafa (_fbed ,_ddcc );for _fbea ,_fdc :=range _dde {_dfea .Set (_fdc ,_fbed [_fbea ]);};case *_g .PdfIndirectObject :_dacb :=[]_g .PdfObject {_dfea .PdfObject };_dafa (_dacb ,_ddcc );_dfea .PdfObject =_dacb [0];};};};
// Optimize optimizes PDF objects to decrease PDF size.
func (_gbfg *Image )Optimize (objects []_g .PdfObject )(_cee []_g .PdfObject ,_dcfa error ){if _gbfg .ImageQuality <=0{return objects ,nil ;};_defa :=_bbg (objects );if len (_defa )==0{return objects ,nil ;};_gae :=make (map[_g .PdfObject ]_g .PdfObject );_agcg :=make (map[_g .PdfObject ]struct{});for _ ,_bad :=range _defa {_gcc :=_bad .Stream .PdfObjectDictionary .Get (_g .PdfObjectName ("\u0053\u004d\u0061s\u006b"));_agcg [_gcc ]=struct{}{};};for _daf ,_fge :=range _defa {_ffcf :=_fge .Stream ;if _ ,_badb :=_agcg [_ffcf ];_badb {continue ;};_efbf ,_fegg :=_g .NewEncoderFromStream (_ffcf );if _fegg !=nil {_fe .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 ;};_aebe ,_fegg :=_efbf .DecodeStream (_ffcf );if _fegg !=nil {_fe .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 ;};_aea :=_g .NewDCTEncoder ();_aea .ColorComponents =_fge .ColorComponents ;_aea .Quality =_gbfg .ImageQuality ;_aea .BitsPerComponent =_fge .BitsPerComponent ;_aea .Width =_fge .Width ;_aea .Height =_fge .Height ;_dage ,_fegg :=_aea .EncodeBytes (_aebe );if _fegg !=nil {_fe .Log .Debug ("\u0045R\u0052\u004f\u0052\u003a\u0020\u0025v",_fegg );return nil ,_fegg ;};var _fcdg _g .StreamEncoder ;_fcdg =_aea ;{_ebad :=_g .NewFlateEncoder ();_fgbd :=_g .NewMultiEncoder ();_fgbd .AddEncoder (_ebad );_fgbd .AddEncoder (_aea );_edec ,_dge :=_fgbd .EncodeBytes (_aebe );if _dge !=nil {return nil ,_dge ;};if len (_edec )< len (_dage ){_fe .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 (_dage ),len (_edec ),len (_ffcf .Stream ));_dage =_edec ;_fcdg =_fgbd ;};};_dcac :=len (_ffcf .Stream );if _dcac < len (_dage ){continue ;};_cbd :=&_g .PdfObjectStream {Stream :_dage };_cbd .PdfObjectReference =_ffcf .PdfObjectReference ;_cbd .PdfObjectDictionary =_g .MakeDict ();_cbd .Merge (_ffcf .PdfObjectDictionary );_cbd .Merge (_fcdg .MakeStreamDict ());_cbd .Set ("\u004c\u0065\u006e\u0067\u0074\u0068",_g .MakeInteger (int64 (len (_dage ))));_gae [_ffcf ]=_cbd ;_defa [_daf ].Stream =_cbd ;};_cee =make ([]_g .PdfObject ,len (objects ));copy (_cee ,objects );_dafa (_cee ,_gae );return _cee ,nil ;};
// Optimize optimizes PDF objects to decrease PDF size.
func (_eec *CleanFonts )Optimize (objects []_g .PdfObject )(_bec []_g .PdfObject ,_cdd error ){var _abe map[*_g .PdfObjectStream ]struct{};if _eec .Subset {var _cf error ;_abe ,_cf =_dfc (objects );if _cf !=nil {return nil ,_cf ;};};for _ ,_cfg :=range objects {_aed ,_gdg :=_g .GetStream (_cfg );if !_gdg {continue ;};if _ ,_eecc :=_abe [_aed ];_eecc {continue ;};_ad ,_caa :=_g .NewEncoderFromStream (_aed );if _caa !=nil {_fe .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",_caa );continue ;};_eeca ,_caa :=_ad .DecodeStream (_aed );if _caa !=nil {_fe .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",_caa );continue ;};if len (_eeca )< 4{continue ;};_bfb :=string (_eeca [:4]);if _bfb =="\u004f\u0054\u0054\u004f"{continue ;};if _bfb !="\u0000\u0001\u0000\u0000"&&_bfb !="\u0074\u0072\u0075\u0065"{continue ;};_abeb ,_caa :=_dfa .Parse (_a .NewReader (_eeca ));if _caa !=nil {_fe .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",_caa );continue ;};_caa =_abeb .Optimize ();if _caa !=nil {continue ;};var _ecc _a .Buffer ;_caa =_abeb .Write (&_ecc );if _caa !=nil {_fe .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",_caa );continue ;};if _ecc .Len ()> len (_eeca ){_fe .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 ;};_bbc ,_caa :=_g .MakeStream (_ecc .Bytes (),_g .NewFlateEncoder ());if _caa !=nil {continue ;};*_aed =*_bbc ;_aed .Set ("\u004ce\u006e\u0067\u0074\u0068\u0031",_g .MakeInteger (int64 (_ecc .Len ())));};return objects ,nil ;};type objectStructure struct{_afbf *_g .PdfObjectDictionary ;_dded *_g .PdfObjectDictionary ;_dcc []*_g .PdfIndirectObject ;};
// Optimize optimizes PDF objects to decrease PDF size.
func (_gbf *CombineDuplicateStreams )Optimize (objects []_g .PdfObject )(_cag []_g .PdfObject ,_cbc error ){_gafec :=make (map[_g .PdfObject ]_g .PdfObject );_gde :=make (map[_g .PdfObject ]struct{});_gegg :=make (map[string ][]*_g .PdfObjectStream );for _ ,_cga :=range objects {if _ffbc ,_ecca :=_cga .(*_g .PdfObjectStream );_ecca {_ccd :=_df .New ();_ccd .Write ([]byte (_ffbc .Stream ));_adgbd :=string (_ccd .Sum (nil ));_gegg [_adgbd ]=append (_gegg [_adgbd ],_ffbc );};};for _ ,_gcf :=range _gegg {if len (_gcf )< 2{continue ;};_cdb :=_gcf [0];for _cce :=1;_cce < len (_gcf );_cce ++{_ffff :=_gcf [_cce ];_gafec [_ffff ]=_cdb ;_gde [_ffff ]=struct{}{};};};_cag =make ([]_g .PdfObject ,0,len (objects )-len (_gde ));for _ ,_eaa :=range objects {if _ ,_gbb :=_gde [_eaa ];_gbb {continue ;};_cag =append (_cag ,_eaa );};_dafa (_cag ,_gafec );return _cag ,nil ;};func _eadg (_dbag []_g .PdfObject ){for _eagf ,_gebc :=range _dbag {switch _dbe :=_gebc .(type ){case *_g .PdfIndirectObject :_dbe .ObjectNumber =int64 (_eagf +1);_dbe .GenerationNumber =0;case *_g .PdfObjectStream :_dbe .ObjectNumber =int64 (_eagf +1);_dbe .GenerationNumber =0;case *_g .PdfObjectStreams :_dbe .ObjectNumber =int64 (_eagf +1);_dbe .GenerationNumber =0;};};};func _bbg (_fdg []_g .PdfObject )[]*imageInfo {_ffbcd :=_g .PdfObjectName ("\u0053u\u0062\u0074\u0079\u0070\u0065");_bge :=make (map[*_g .PdfObjectStream ]struct{});var _bde error ;var _fgf []*imageInfo ;for _ ,_gdcd :=range _fdg {_aeb ,_ggge :=_g .GetStream (_gdcd );if !_ggge {continue ;};if _ ,_ecb :=_bge [_aeb ];_ecb {continue ;};_bge [_aeb ]=struct{}{};_afed :=_aeb .PdfObjectDictionary .Get (_ffbcd );_gee ,_ggge :=_g .GetName (_afed );if !_ggge ||string (*_gee )!="\u0049\u006d\u0061g\u0065"{continue ;};_dfcc :=&imageInfo {BitsPerComponent :8,Stream :_aeb };if _dfcc .ColorSpace ,_bde =_ec .DetermineColorspaceNameFromPdfObject (_aeb .PdfObjectDictionary .Get ("\u0043\u006f\u006c\u006f\u0072\u0053\u0070\u0061\u0063\u0065"));_bde !=nil {_fe .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",_bde );continue ;};if _bef ,_dcaa :=_g .GetIntVal (_aeb .PdfObjectDictionary .Get ("\u0042\u0069t\u0073\u0050\u0065r\u0043\u006f\u006d\u0070\u006f\u006e\u0065\u006e\u0074"));_dcaa {_dfcc .BitsPerComponent =_bef ;};if _bcc ,_eabf :=_g .GetIntVal (_aeb .PdfObjectDictionary .Get ("\u0057\u0069\u0064t\u0068"));_eabf {_dfcc .Width =_bcc ;};if _cfd ,_egfd :=_g .GetIntVal (_aeb .PdfObjectDictionary .Get ("\u0048\u0065\u0069\u0067\u0068\u0074"));_egfd {_dfcc .Height =_cfd ;};switch _dfcc .ColorSpace {case "\u0044e\u0076\u0069\u0063\u0065\u0052\u0047B":_dfcc .ColorComponents =3;case "\u0044\u0065\u0076\u0069\u0063\u0065\u0047\u0072\u0061\u0079":_dfcc .ColorComponents =1;default:_fe .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",_dfcc .ColorSpace );continue ;};_fgf =append (_fgf ,_dfcc );};return _fgf ;};
// CombineIdenticalIndirectObjects combines identical indirect objects.
// It implements interface model.Optimizer.
type CombineIdenticalIndirectObjects struct{};
// CombineDuplicateStreams combines duplicated streams by its data hash.
// It implements interface model.Optimizer.
type CombineDuplicateStreams 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 ;};type content struct{_bga string ;_ggg *_ec .PdfPageResources ;};func _bg (_fb *_g .PdfObjectStream ,_gca []rune ,_dcb []_dfa .GlyphIndex )error {_fb ,_aba :=_g .GetStream (_fb );if !_aba {_fe .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 _cc .New ("\u0066\u006f\u006e\u0074fi\u006c\u0065\u0032\u0020\u006e\u006f\u0074\u0020\u0066\u006f\u0075\u006e\u0064");};_bab ,_gf :=_g .DecodeStream (_fb );if _gf !=nil {_fe .Log .Debug ("\u0044\u0065c\u006f\u0064\u0065 \u0065\u0072\u0072\u006f\u0072\u003a\u0020\u0025\u0076",_gf );return _gf ;};_efb ,_gf :=_dfa .Parse (_a .NewReader (_bab ));if _gf !=nil {_fe .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 (_fb .Stream ));return _gf ;};_gaf :=_dcb ;if len (_gca )> 0{_gfa :=_efb .LookupRunes (_gca );_gaf =append (_gaf ,_gfa ...);};_efb ,_gf =_efb .SubsetKeepIndices (_gaf );if _gf !=nil {_fe .Log .Debug ("\u0045R\u0052\u004f\u0052\u0020s\u0075\u0062\u0073\u0065\u0074t\u0069n\u0067 \u0066\u006f\u006e\u0074\u003a\u0020\u0025v",_gf );return _gf ;};var _efa _a .Buffer ;_gf =_efb .Write (&_efa );if _gf !=nil {_fe .Log .Debug ("\u0045\u0052\u0052\u004fR \u0057\u0072\u0069\u0074\u0069\u006e\u0067\u0020\u0066\u006f\u006e\u0074\u003a\u0020%\u0076",_gf );return _gf ;};if _efa .Len ()> len (_bab ){_fe .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 ;};_cgce ,_gf :=_g .MakeStream (_efa .Bytes (),_g .NewFlateEncoder ());if _gf !=nil {_fe .Log .Debug ("\u0045\u0052\u0052\u004fR \u0057\u0072\u0069\u0074\u0069\u006e\u0067\u0020\u0066\u006f\u006e\u0074\u003a\u0020%\u0076",_gf );return _gf ;};*_fb =*_cgce ;_fb .Set ("\u004ce\u006e\u0067\u0074\u0068\u0031",_g .MakeInteger (int64 (_efa .Len ())));return nil ;};
// Optimize optimizes PDF objects to decrease PDF size.
func (_agcf *ImagePPI )Optimize (objects []_g .PdfObject )(_gag []_g .PdfObject ,_eaae error ){if _agcf .ImageUpperPPI <=0{return objects ,nil ;};_aad :=_bbg (objects );if len (_aad )==0{return objects ,nil ;};_bdee :=make (map[_g .PdfObject ]struct{});for _ ,_abg :=range _aad {_gfe :=_abg .Stream .PdfObjectDictionary .Get (_g .PdfObjectName ("\u0053\u004d\u0061s\u006b"));_bdee [_gfe ]=struct{}{};};_cgcd :=make (map[*_g .PdfObjectStream ]*imageInfo );for _ ,_bac :=range _aad {_cgcd [_bac .Stream ]=_bac ;};var _gabb *_g .PdfObjectDictionary ;for _ ,_fgfb :=range objects {if _cbca ,_gcab :=_g .GetDict (_fgfb );_gabb ==nil &&_gcab {if _afbb ,_gdca :=_g .GetName (_cbca .Get (_g .PdfObjectName ("\u0054\u0079\u0070\u0065")));_gdca &&*_afbb =="\u0043a\u0074\u0061\u006c\u006f\u0067"{_gabb =_cbca ;};};};if _gabb ==nil {return objects ,nil ;};_gege ,_dbb :=_g .GetDict (_gabb .Get (_g .PdfObjectName ("\u0050\u0061\u0067e\u0073")));if !_dbb {return objects ,nil ;};_cad ,_beag :=_g .GetArray (_gege .Get (_g .PdfObjectName ("\u004b\u0069\u0064\u0073")));if !_beag {return objects ,nil ;};_bggb :=make (map[string ]*imageInfo );for _ ,_fgdf :=range _cad .Elements (){_ceba ,_fbe :=_g .GetDict (_fgdf );if !_fbe {continue ;};_eae ,_aga :=_g .GetArray (_ceba .Get ("\u0043\u006f\u006e\u0074\u0065\u006e\u0074\u0073"));if !_aga {continue ;};_geef ,_bda :=_g .GetDict (_ceba .Get ("\u0052e\u0073\u006f\u0075\u0072\u0063\u0065s"));if !_bda {continue ;};_cecb ,_aedd :=_g .GetDict (_geef .Get ("\u0058O\u0062\u006a\u0065\u0063\u0074"));if !_aedd {continue ;};_dgeb :=_cecb .Keys ();for _ ,_ceef :=range _dgeb {if _agg ,_gac :=_g .GetStream (_cecb .Get (_ceef ));_gac {if _fce ,_gfg :=_cgcd [_agg ];_gfg {_bggb [string (_ceef )]=_fce ;};};};for _ ,_gacb :=range _eae .Elements (){if _geec ,_afgf :=_g .GetStream (_gacb );_afgf {_aca ,_aabd :=_g .NewEncoderFromStream (_geec );if _aabd !=nil {return nil ,_aabd ;};_fbd ,_aabd :=_aca .DecodeStream (_geec );if _aabd !=nil {return nil ,_aabd ;};_beee :=_ee .NewContentStreamParser (string (_fbd ));_dgae ,_aabd :=_beee .Parse ();if _aabd !=nil {return nil ,_aabd ;};_bdb ,_cceg :=1.0,1.0;for _ ,_aebc :=range *_dgae {if _aebc .Operand =="\u0051"{_bdb ,_cceg =1.0,1.0;};if _aebc .Operand =="\u0063\u006d"&&len (_aebc .Params )==6{if _eaaa ,_bbdc :=_g .GetFloatVal (_aebc .Params [0]);_bbdc {_bdb =_bdb *_eaaa ;};if _gbd ,_cdc :=_g .GetFloatVal (_aebc .Params [3]);_cdc {_cceg =_cceg *_gbd ;};if _dea ,_acgg :=_g .GetIntVal (_aebc .Params [0]);_acgg {_bdb =_bdb *float64 (_dea );};if _gfff ,_gfgg :=_g .GetIntVal (_aebc .Params [3]);_gfgg {_cceg =_cceg *float64 (_gfff );};};if _aebc .Operand =="\u0044\u006f"&&len (_aebc .Params )==1{_egc ,_acgd :=_g .GetName (_aebc .Params [0]);if !_acgd {continue ;};if _fgg ,_ead :=_bggb [string (*_egc )];_ead {_cccg ,_cda :=_bdb /72.0,_cceg /72.0;_fea ,_ecfe :=float64 (_fgg .Width )/_cccg ,float64 (_fgg .Height )/_cda ;if _cccg ==0||_cda ==0{_fea =72.0;_ecfe =72.0;};_fgg .PPI =_fg .Max (_fgg .PPI ,_fea );_fgg .PPI =_fg .Max (_fgg .PPI ,_ecfe );};};};};};};for _ ,_dbd :=range _aad {if _ ,_fabc :=_bdee [_dbd .Stream ];_fabc {continue ;};if _dbd .PPI <=_agcf .ImageUpperPPI {continue ;};_cef :=_agcf .ImageUpperPPI /_dbd .PPI ;if _ebc :=_aeg (_dbd .Stream ,_cef );_ebc !=nil {_fe .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",_ebc );}else {if _bcce ,_ceca :=_g .GetStream (_dbd .Stream .PdfObjectDictionary .Get (_g .PdfObjectName ("\u0053\u004d\u0061s\u006b")));_ceca {if _acb :=_aeg (_bcce ,_cef );_acb !=nil {return nil ,_acb ;};};};};return objects ,nil ;};func _aeg (_gdd *_g .PdfObjectStream ,_ceeb float64 )error {_agce ,_acga :=_ec .NewXObjectImageFromStream (_gdd );if _acga !=nil {return _acga ;};_fgef ,_acga :=_agce .ToImage ();if _acga !=nil {return _acga ;};_gdcb ,_acga :=_fgef .ToGoImage ();if _acga !=nil {return _acga ;};_bbdgb :=int (_fg .RoundToEven (float64 (_fgef .Width )*_ceeb ));_gdaf :=int (_fg .RoundToEven (float64 (_fgef .Height )*_ceeb ));_dac :=_d .Rect (0,0,_bbdgb ,_gdaf );var _cgf _c .Image ;var _fgd func (_d .Image )(*_ec .Image ,error );switch _agce .ColorSpace .String (){case "\u0044e\u0076\u0069\u0063\u0065\u0052\u0047B":_cgf =_d .NewRGBA (_dac );_fgd =_ec .ImageHandling .NewImageFromGoImage ;case "\u0044\u0065\u0076\u0069\u0063\u0065\u0047\u0072\u0061\u0079":_cgf =_d .NewGray (_dac );_fgd =_ec .ImageHandling .NewGrayImageFromGoImage ;default:return _e .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",_agce .ColorSpace .String ());};_c .CatmullRom .Scale (_cgf ,_cgf .Bounds (),_gdcb ,_gdcb .Bounds (),_c .Over ,&_c .Options {});if _fgef ,_acga =_fgd (_cgf );_acga !=nil {return _acga ;};_cbde :=_g .MakeDict ();_cbde .Set ("\u0051u\u0061\u006c\u0069\u0074\u0079",_g .MakeInteger (100));_cbde .Set ("\u0050r\u0065\u0064\u0069\u0063\u0074\u006fr",_g .MakeInteger (1));_agce .Filter .UpdateParams (_cbde );if _acga =_agce .SetImage (_fgef ,nil );_acga !=nil {return _acga ;};_agce .ToPdfObject ();return nil ;};
// CompressStreams compresses uncompressed streams.
// It implements interface model.Optimizer.
type CompressStreams struct{};func _cd (_ab *_ee .ContentStreamOperations )*_ee .ContentStreamOperations {if _ab ==nil {return nil ;};_eb :=_ee .ContentStreamOperations {};for _ ,_ccc :=range *_ab {switch _ccc .Operand {case "\u0042\u0044\u0043","\u0042\u004d\u0043","\u0045\u004d\u0043":continue ;case "\u0054\u006d":if len (_ccc .Params )==6{if _ce ,_ced :=_g .GetNumbersAsFloat (_ccc .Params );_ced ==nil {if _ce [0]==1&&_ce [1]==0&&_ce [2]==0&&_ce [3]==1{_ccc =&_ee .ContentStreamOperation {Params :[]_g .PdfObject {_ccc .Params [4],_ccc .Params [5]},Operand :"\u0054\u0064"};};};};};_eb =append (_eb ,_ccc );};return &_eb ;};func _ag (_bf *_g .PdfObjectStream )error {_dc ,_ge :=_g .DecodeStream (_bf );if _ge !=nil {return _ge ;};_agc :=_ee .NewContentStreamParser (string (_dc ));_dca ,_ge :=_agc .Parse ();if _ge !=nil {return _ge ;};_dca =_cd (_dca );_de :=_dca .Bytes ();if len (_de )>=len (_dc ){return nil ;};_dfad ,_ge :=_g .MakeStream (_dca .Bytes (),_g .NewFlateEncoder ());if _ge !=nil {return _ge ;};_bf .Stream =_dfad .Stream ;_bf .Merge (_dfad .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 ;};func _egcf (_aecf _g .PdfObject )(_gceg string ,_gddd []_g .PdfObject ){var _efe _a .Buffer ;switch _ggbb :=_aecf .(type ){case *_g .PdfIndirectObject :_gddd =append (_gddd ,_ggbb );_aecf =_ggbb .PdfObject ;};switch _dbba :=_aecf .(type ){case *_g .PdfObjectStream :if _acc ,_bbgb :=_g .DecodeStream (_dbba );_bbgb ==nil {_efe .Write (_acc );_gddd =append (_gddd ,_dbba );};case *_g .PdfObjectArray :for _ ,_caab :=range _dbba .Elements (){switch _acca :=_caab .(type ){case *_g .PdfObjectStream :if _cfcd ,_gcad :=_g .DecodeStream (_acca );_gcad ==nil {_efe .Write (_cfcd );_gddd =append (_gddd ,_acca );};};};};return _efe .String (),_gddd ;};
// Optimize optimizes PDF objects to decrease PDF size.
func (_eea *CombineIdenticalIndirectObjects )Optimize (objects []_g .PdfObject )(_abc []_g .PdfObject ,_agba error ){_eadg (objects );_babb :=make (map[_g .PdfObject ]_g .PdfObject );_dga :=make (map[_g .PdfObject ]struct{});_afb :=make (map[string ][]*_g .PdfIndirectObject );for _ ,_ccdb :=range objects {_eab ,_bcd :=_ccdb .(*_g .PdfIndirectObject );if !_bcd {continue ;};if _aaec ,_dee :=_eab .PdfObject .(*_g .PdfObjectDictionary );_dee {if _aedg ,_egf :=_aaec .Get ("\u0054\u0079\u0070\u0065").(*_g .PdfObjectName );_egf &&*_aedg =="\u0050\u0061\u0067\u0065"{continue ;};_gef :=_df .New ();_gef .Write ([]byte (_aaec .WriteString ()));_ede :=string (_gef .Sum (nil ));_afb [_ede ]=append (_afb [_ede ],_eab );};};for _ ,_abae :=range _afb {if len (_abae )< 2{continue ;};_dedf :=_abae [0];for _bbdb :=1;_bbdb < len (_abae );_bbdb ++{_degd :=_abae [_bbdb ];_babb [_degd ]=_dedf ;_dga [_degd ]=struct{}{};};};_abc =make ([]_g .PdfObject ,0,len (objects )-len (_dga ));for _ ,_agde :=range objects {if _ ,_egff :=_dga [_agde ];_egff {continue ;};_abc =append (_abc ,_agde );};_dafa (_abc ,_babb );return _abc ,nil ;};
// Chain allows to use sequence of optimizers.
// It implements interface model.Optimizer.
type Chain struct{_af []_ec .Optimizer };
// New creates a optimizers chain from options.
func New (options Options )*Chain {_ddf :=new (Chain );if options .CleanFonts ||options .SubsetFonts {_ddf .Append (&CleanFonts {Subset :options .SubsetFonts });};if options .CleanContentstream {_ddf .Append (new (CleanContentstream ));};if options .ImageUpperPPI > 0{_gcfa :=new (ImagePPI );_gcfa .ImageUpperPPI =options .ImageUpperPPI ;_ddf .Append (_gcfa );};if options .ImageQuality > 0{_fga :=new (Image );_fga .ImageQuality =options .ImageQuality ;_ddf .Append (_fga );};if options .CombineDuplicateDirectObjects {_ddf .Append (new (CombineDuplicateDirectObjects ));};if options .CombineDuplicateStreams {_ddf .Append (new (CombineDuplicateStreams ));};if options .CombineIdenticalIndirectObjects {_ddf .Append (new (CombineIdenticalIndirectObjects ));};if options .UseObjectStreams {_ddf .Append (new (ObjectStreams ));};if options .CompressStreams {_ddf .Append (new (CompressStreams ));};return _ddf ;};
// 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 (_gd *CleanContentstream )Optimize (objects []_g .PdfObject )(_feg []_g .PdfObject ,_fcd error ){_fcdc :=map[*_g .PdfObjectStream ]struct{}{};var _da []*_g .PdfObjectStream ;_db :=func (_eg *_g .PdfObjectStream ){if _ ,_ae :=_fcdc [_eg ];!_ae {_fcdc [_eg ]=struct{}{};_da =append (_da ,_eg );};};for _ ,_fege :=range objects {switch _gad :=_fege .(type ){case *_g .PdfIndirectObject :switch _bc :=_gad .PdfObject .(type ){case *_g .PdfObjectDictionary :if _gge ,_dag :=_g .GetName (_bc .Get ("\u0054\u0079\u0070\u0065"));!_dag ||_gge .String ()!="\u0050\u0061\u0067\u0065"{continue ;};if _gab ,_dfe :=_g .GetStream (_bc .Get ("\u0043\u006f\u006e\u0074\u0065\u006e\u0074\u0073"));_dfe {_db (_gab );}else if _bfc ,_bff :=_g .GetArray (_bc .Get ("\u0043\u006f\u006e\u0074\u0065\u006e\u0074\u0073"));_bff {for _ ,_geg :=range _bfc .Elements (){if _ef ,_ggf :=_g .GetStream (_geg );_ggf {_db (_ef );};};};};case *_g .PdfObjectStream :if _aec ,_bb :=_g .GetName (_gad .Get ("\u0054\u0079\u0070\u0065"));!_bb ||_aec .String ()!="\u0058O\u0062\u006a\u0065\u0063\u0074"{continue ;};if _cb ,_egg :=_g .GetName (_gad .Get ("\u0053u\u0062\u0074\u0079\u0070\u0065"));!_egg ||_cb .String ()!="\u0046\u006f\u0072\u006d"{continue ;};_db (_gad );};};for _ ,_ece :=range _da {_fcd =_ag (_ece );if _fcd !=nil {return nil ,_fcd ;};};return objects ,nil ;};type imageInfo struct{ColorSpace _g .PdfObjectName ;BitsPerComponent int ;ColorComponents int ;Width int ;Height int ;Stream *_g .PdfObjectStream ;PPI float64 ;};
// Optimize optimizes PDF objects to decrease PDF size.
func (_eefac *CompressStreams )Optimize (objects []_g .PdfObject )(_cggdd []_g .PdfObject ,_edf error ){_cggdd =make ([]_g .PdfObject ,len (objects ));copy (_cggdd ,objects );for _ ,_gggd :=range objects {_fae ,_cdf :=_g .GetStream (_gggd );if !_cdf {continue ;};if _cfeg :=_fae .Get ("\u0046\u0069\u006c\u0074\u0065\u0072");_cfeg !=nil {if _ ,_dgb :=_g .GetName (_cfeg );_dgb {continue ;};if _gcaa ,_ddgg :=_g .GetArray (_cfeg );_ddgg &&_gcaa .Len ()> 0{continue ;};};_efd :=_g .NewFlateEncoder ();var _bce []byte ;_bce ,_edf =_efd .EncodeBytes (_fae .Stream );if _edf !=nil {return _cggdd ,_edf ;};_faa :=_efd .MakeStreamDict ();if len (_bce )+len (_faa .WriteString ())< len (_fae .Stream ){_fae .Stream =_bce ;_fae .PdfObjectDictionary .Merge (_faa );_fae .PdfObjectDictionary .Set ("\u004c\u0065\u006e\u0067\u0074\u0068",_g .MakeInteger (int64 (len (_fae .Stream ))));};};return _cggdd ,nil ;};
// ObjectStreams groups PDF objects to object streams.
// It implements interface model.Optimizer.
type ObjectStreams struct{};
// Optimize optimizes PDF objects to decrease PDF size.
func (_age *CombineDuplicateDirectObjects )Optimize (objects []_g .PdfObject )(_faf []_g .PdfObject ,_bee error ){_eadg (objects );_ddba :=make (map[string ][]*_g .PdfObjectDictionary );var _debb func (_ecf *_g .PdfObjectDictionary );_debb =func (_caf *_g .PdfObjectDictionary ){for _ ,_ebb :=range _caf .Keys (){_dcfd :=_caf .Get (_ebb );if _aage ,_eacb :=_dcfd .(*_g .PdfObjectDictionary );_eacb {_ffb :=_df .New ();_ffb .Write ([]byte (_aage .WriteString ()));_dba :=string (_ffb .Sum (nil ));_ddba [_dba ]=append (_ddba [_dba ],_aage );_debb (_aage );};};};for _ ,_gdc :=range objects {_agb ,_bbdg :=_gdc .(*_g .PdfIndirectObject );if !_bbdg {continue ;};if _eebd ,_ggb :=_agb .PdfObject .(*_g .PdfObjectDictionary );_ggb {_debb (_eebd );};};_bcgg :=make ([]_g .PdfObject ,0,len (_ddba ));_dbf :=make (map[_g .PdfObject ]_g .PdfObject );for _ ,_ded :=range _ddba {if len (_ded )< 2{continue ;};_adgb :=_g .MakeDict ();_adgb .Merge (_ded [0]);_gafe :=_g .MakeIndirectObject (_adgb );_bcgg =append (_bcgg ,_gafe );for _ffg :=0;_ffg < len (_ded );_ffg ++{_ade :=_ded [_ffg ];_dbf [_ade ]=_gafe ;};};_faf =make ([]_g .PdfObject ,len (objects ));copy (_faf ,objects );_faf =append (_bcgg ,_faf ...);_dafa (_faf ,_dbf );return _faf ,nil ;};func _ceb (_ddb _g .PdfObject )[]content {if _ddb ==nil {return nil ;};_edc ,_cfe :=_g .GetArray (_ddb );if !_cfe {_fe .Log .Debug ("\u0041\u006e\u006e\u006fts\u0020\u006e\u006f\u0074\u0020\u0061\u006e\u0020\u0061\u0072\u0072\u0061\u0079");return nil ;};var _fa []content ;for _ ,_gbe :=range _edc .Elements (){_gaa ,_gdgb :=_g .GetDict (_gbe );if !_gdgb {_fe .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 ;};_bgf ,_gdgb :=_g .GetDict (_gaa .Get ("\u0041\u0050"));if !_gdgb {_fe .Log .Debug ("\u004e\u006f\u0020\u0041P \u0065\u006e\u0074\u0072\u0079\u0020\u002d\u0020\u0073\u006b\u0069\u0070\u0070\u0069n\u0067");continue ;};_dce :=_g .TraceToDirectObject (_bgf .Get ("\u004e"));if _dce ==nil {_fe .Log .Debug ("N\u006f\u0020\u004e\u0020en\u0074r\u0079\u0020\u002d\u0020\u0073k\u0069\u0070\u0070\u0069\u006e\u0067");continue ;};var _fgbg *_g .PdfObjectStream ;switch _bfe :=_dce .(type ){case *_g .PdfObjectDictionary :_eeb ,_gff :=_g .GetName (_gaa .Get ("\u0041\u0053"));if !_gff {_fe .Log .Debug ("\u004e\u006f\u0020\u0041S \u0065\u006e\u0074\u0072\u0079\u0020\u002d\u0020\u0073\u006b\u0069\u0070\u0070\u0069n\u0067");continue ;};_fgbg ,_gff =_g .GetStream (_bfe .Get (*_eeb ));if !_gff {_fe .Log .Debug ("\u0046o\u0072\u006d\u0020\u006eo\u0074\u0020\u0066\u006f\u0075n\u0064 \u002d \u0073\u006b\u0069\u0070\u0070\u0069\u006eg");continue ;};case *_g .PdfObjectStream :_fgbg =_bfe ;};if _fgbg ==nil {_fe .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 ;};_bgg ,_eac :=_ec .NewXObjectFormFromStream (_fgbg );if _eac !=nil {_fe .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",_eac );continue ;};_dg ,_eac :=_bgg .GetContentStream ();if _eac !=nil {_fe .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",_eac );continue ;};_fa =append (_fa ,content {_bga :string (_dg ),_ggg :_bgg .Resources });};return _fa ;};
// CombineDuplicateDirectObjects combines duplicated direct objects by its data hash.
// It implements interface model.Optimizer.
type CombineDuplicateDirectObjects struct{};func _ggec (_fffc []_g .PdfObject )objectStructure {_gggg :=objectStructure {};_cdad :=false ;for _ ,_deac :=range _fffc {switch _ggfd :=_deac .(type ){case *_g .PdfIndirectObject :_ddcf ,_cdcf :=_g .GetDict (_ggfd );if !_cdcf {continue ;};_edfe ,_cdcf :=_g .GetName (_ddcf .Get ("\u0054\u0079\u0070\u0065"));if !_cdcf {continue ;};switch _edfe .String (){case "\u0043a\u0074\u0061\u006c\u006f\u0067":_gggg ._afbf =_ddcf ;_cdad =true ;};};if _cdad {break ;};};if !_cdad {return _gggg ;};_fdb ,_cfa :=_g .GetDict (_gggg ._afbf .Get ("\u0050\u0061\u0067e\u0073"));if !_cfa {return _gggg ;};_gggg ._dded =_fdb ;_dgg ,_cfa :=_g .GetArray (_fdb .Get ("\u004b\u0069\u0064\u0073"));if !_cfa {return _gggg ;};for _ ,_efg :=range _dgg .Elements (){_beef ,_cagb :=_g .GetIndirect (_efg );if !_cagb {break ;};_gggg ._dcc =append (_gggg ._dcc ,_beef );};return _gggg ;};
// Append appends optimizers to the chain.
func (_fd *Chain )Append (optimizers ..._ec .Optimizer ){_fd ._af =append (_fd ._af ,optimizers ...)};
// 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{};