unipdf/model/optimize/optimize.go

211 lines
37 KiB
Go
Raw Normal View History

2020-08-27 21:45:09 +00:00
//
// 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/
2021-09-23 22:37:42 +00:00
package optimize ;import (_gb "bytes";_eg "crypto/md5";_fa "errors";_e "github.com/unidoc/unipdf/v3/common";_g "github.com/unidoc/unipdf/v3/contentstream";_bb "github.com/unidoc/unipdf/v3/core";_eb "github.com/unidoc/unipdf/v3/extractor";_a "github.com/unidoc/unipdf/v3/internal/imageutil";
_ee "github.com/unidoc/unipdf/v3/internal/textencoding";_c "github.com/unidoc/unipdf/v3/model";_bf "github.com/unidoc/unitype";_f "golang.org/x/image/draw";_d "math";);
2021-07-30 00:21:16 +00:00
// ObjectStreams groups PDF objects to object streams.
2021-06-21 14:01:56 +00:00
// It implements interface model.Optimizer.
2021-08-13 01:33:42 +00:00
type ObjectStreams struct{};
2021-07-30 00:21:16 +00:00
2021-09-23 22:37:42 +00:00
// 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{};type content struct{_feac string ;_dbd *_c .PdfPageResources ;};
2021-04-17 13:46:54 +00:00
2021-09-23 22:37:42 +00:00
// Chain allows to use sequence of optimizers.
2021-07-30 00:21:16 +00:00
// It implements interface model.Optimizer.
2021-09-23 22:37:42 +00:00
type Chain struct{_ef []_c .Optimizer };
2021-05-31 17:17:31 +00:00
2021-07-30 00:21:16 +00:00
// Optimize optimizes PDF objects to decrease PDF size.
2021-09-23 22:37:42 +00:00
func (_dead *ObjectStreams )Optimize (objects []_bb .PdfObject )(_dacb []_bb .PdfObject ,_fecb error ){_cfgd :=&_bb .PdfObjectStreams {};_fbcc :=make ([]_bb .PdfObject ,0,len (objects ));for _ ,_agga :=range objects {if _baa ,_bffca :=_agga .(*_bb .PdfIndirectObject );
_bffca &&_baa .GenerationNumber ==0{_cfgd .Append (_agga );}else {_fbcc =append (_fbcc ,_agga );};};if _cfgd .Len ()==0{return _fbcc ,nil ;};_dacb =make ([]_bb .PdfObject ,0,len (_fbcc )+_cfgd .Len ()+1);if _cfgd .Len ()> 1{_dacb =append (_dacb ,_cfgd );
};_dacb =append (_dacb ,_cfgd .Elements ()...);_dacb =append (_dacb ,_fbcc ...);return _dacb ,nil ;};
2021-05-11 00:01:27 +00:00
2021-07-30 00:21:16 +00:00
// Optimize optimizes PDF objects to decrease PDF size.
2021-09-23 22:37:42 +00:00
func (_ceb *CombineDuplicateStreams )Optimize (objects []_bb .PdfObject )(_dfe []_bb .PdfObject ,_ga error ){_ade :=make (map[_bb .PdfObject ]_bb .PdfObject );_afb :=make (map[_bb .PdfObject ]struct{});_gfcc :=make (map[string ][]*_bb .PdfObjectStream );
for _ ,_fad :=range objects {if _eegd ,_gca :=_fad .(*_bb .PdfObjectStream );_gca {_caf :=_eg .New ();_caf .Write (_eegd .Stream );_caf .Write ([]byte (_eegd .PdfObjectDictionary .WriteString ()));_bdb :=string (_caf .Sum (nil ));_gfcc [_bdb ]=append (_gfcc [_bdb ],_eegd );
};};for _ ,_bfd :=range _gfcc {if len (_bfd )< 2{continue ;};_ged :=_bfd [0];for _geb :=1;_geb < len (_bfd );_geb ++{_cdb :=_bfd [_geb ];_ade [_cdb ]=_ged ;_afb [_cdb ]=struct{}{};};};_dfe =make ([]_bb .PdfObject ,0,len (objects )-len (_afb ));for _ ,_ggf :=range objects {if _ ,_egdd :=_afb [_ggf ];
_egdd {continue ;};_dfe =append (_dfe ,_ggf );};_cbef (_dfe ,_ade );return _dfe ,nil ;};func _aee (_deb *_bb .PdfObjectStream ,_fdb []rune ,_efg []_bf .GlyphIndex )error {_deb ,_bccc :=_bb .GetStream (_deb );if !_bccc {_e .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 _fa .New ("\u0066\u006f\u006e\u0074fi\u006c\u0065\u0032\u0020\u006e\u006f\u0074\u0020\u0066\u006f\u0075\u006e\u0064");};_beb ,_cgga :=_bb .DecodeStream (_deb );if _cgga !=nil {_e .Log .Debug ("\u0044\u0065c\u006f\u0064\u0065 \u0065\u0072\u0072\u006f\u0072\u003a\u0020\u0025\u0076",_cgga );
return _cgga ;};_dfg ,_cgga :=_bf .Parse (_gb .NewReader (_beb ));if _cgga !=nil {_e .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 (_deb .Stream ));
return _cgga ;};_dca :=_efg ;if len (_fdb )> 0{_cbf :=_dfg .LookupRunes (_fdb );_dca =append (_dca ,_cbf ...);};_dfg ,_cgga =_dfg .SubsetKeepIndices (_dca );if _cgga !=nil {_e .Log .Debug ("\u0045R\u0052\u004f\u0052\u0020s\u0075\u0062\u0073\u0065\u0074t\u0069n\u0067 \u0066\u006f\u006e\u0074\u003a\u0020\u0025v",_cgga );
return _cgga ;};var _ecae _gb .Buffer ;_cgga =_dfg .Write (&_ecae );if _cgga !=nil {_e .Log .Debug ("\u0045\u0052\u0052\u004fR \u0057\u0072\u0069\u0074\u0069\u006e\u0067\u0020\u0066\u006f\u006e\u0074\u003a\u0020%\u0076",_cgga );return _cgga ;};if _ecae .Len ()> len (_beb ){_e .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 ;};_cfgb ,_cgga :=_bb .MakeStream (_ecae .Bytes (),_bb .NewFlateEncoder ());if _cgga !=nil {_e .Log .Debug ("\u0045\u0052\u0052\u004fR \u0057\u0072\u0069\u0074\u0069\u006e\u0067\u0020\u0066\u006f\u006e\u0074\u003a\u0020%\u0076",_cgga );return _cgga ;
};*_deb =*_cfgb ;_deb .Set ("\u004ce\u006e\u0067\u0074\u0068\u0031",_bb .MakeInteger (int64 (_ecae .Len ())));return nil ;};
2021-05-31 17:17:31 +00:00
2021-09-23 22:37:42 +00:00
// Optimize optimizes PDF objects to decrease PDF size.
func (_ffg *ImagePPI )Optimize (objects []_bb .PdfObject )(_ecfca []_bb .PdfObject ,_gfb error ){if _ffg .ImageUpperPPI <=0{return objects ,nil ;};_gdga :=_gcad (objects );if len (_gdga )==0{return objects ,nil ;};_ccea :=make (map[_bb .PdfObject ]struct{});
for _ ,_bea :=range _gdga {_dgae :=_bea .Stream .PdfObjectDictionary .Get ("\u0053\u004d\u0061s\u006b");_ccea [_dgae ]=struct{}{};};_abba :=make (map[*_bb .PdfObjectStream ]*imageInfo );for _ ,_agaf :=range _gdga {_abba [_agaf .Stream ]=_agaf ;};var _ggfb *_bb .PdfObjectDictionary ;
for _ ,_bedf :=range objects {if _cebg ,_fcgg :=_bb .GetDict (_bedf );_ggfb ==nil &&_fcgg {if _bff ,_dbc :=_bb .GetName (_cebg .Get ("\u0054\u0079\u0070\u0065"));_dbc &&*_bff =="\u0043a\u0074\u0061\u006c\u006f\u0067"{_ggfb =_cebg ;};};};if _ggfb ==nil {return objects ,nil ;
};_cgd ,_bebg :=_bb .GetDict (_ggfb .Get ("\u0050\u0061\u0067e\u0073"));if !_bebg {return objects ,nil ;};_ed ,_edd :=_bb .GetArray (_cgd .Get ("\u004b\u0069\u0064\u0073"));if !_edd {return objects ,nil ;};for _ ,_ddbd :=range _ed .Elements (){_eef :=make (map[string ]*imageInfo );
_aaad ,_ddac :=_bb .GetDict (_ddbd );if !_ddac {continue ;};_eea ,_ :=_bdg (_aaad .Get ("\u0043\u006f\u006e\u0074\u0065\u006e\u0074\u0073"));if len (_eea )==0{continue ;};_cddf ,_ffaa :=_bb .GetDict (_aaad .Get ("\u0052e\u0073\u006f\u0075\u0072\u0063\u0065s"));
if !_ffaa {continue ;};_gdcb ,_dbga :=_c .NewPdfPageResourcesFromDict (_cddf );if _dbga !=nil {_e .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",_dbga );
continue ;};_cgaa ,_bggca :=_bb .GetDict (_cddf .Get ("\u0058O\u0062\u006a\u0065\u0063\u0074"));if !_bggca {continue ;};_dea :=_cgaa .Keys ();for _ ,_dcc :=range _dea {if _abac ,_dccb :=_bb .GetStream (_cgaa .Get (_dcc ));_dccb {if _eafe ,_bcb :=_abba [_abac ];
_bcb {_eef [string (_dcc )]=_eafe ;};};};_bfed :=_g .NewContentStreamParser (_eea );_bbce ,_dbga :=_bfed .Parse ();if _dbga !=nil {_e .Log .Debug ("\u0045\u0052\u0052\u004f\u0052\u003a\u0020\u0025\u002b\u0076",_dbga );continue ;};_dbe :=_g .NewContentStreamProcessor (*_bbce );
_dbe .AddHandler (_g .HandlerConditionEnumAllOperands ,"",func (_ffea *_g .ContentStreamOperation ,_acff _g .GraphicsState ,_ebfe *_c .PdfPageResources )error {switch _ffea .Operand {case "\u0044\u006f":if len (_ffea .Params )!=1{_e .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 ;};_dbeb ,_dag :=_bb .GetName (_ffea .Params [0]);if !_dag {_e .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 _cgb ,_cbaa :=_eef [string (*_dbeb )];_cbaa {_ccf :=_acff .CTM .ScalingFactorX ();_cbbb :=_acff .CTM .ScalingFactorY ();_ccfg ,_bggfb :=_ccf /72.0,_cbbb /72.0;_abe ,_aac :=float64 (_cgb .Width )/_ccfg ,float64 (_cgb .Height )/_bggfb ;if _ccfg ==0||_bggfb ==0{_abe =72.0;
_aac =72.0;};_cgb .PPI =_d .Max (_cgb .PPI ,_abe );_cgb .PPI =_d .Max (_cgb .PPI ,_aac );};};return nil ;});_dbga =_dbe .Process (_gdcb );if _dbga !=nil {_e .Log .Debug ("E\u0052\u0052\u004f\u0052 p\u0072o\u0063\u0065\u0073\u0073\u0069n\u0067\u003a\u0020\u0025\u002b\u0076",_dbga );
continue ;};};for _ ,_fac :=range _gdga {if _ ,_dcaa :=_ccea [_fac .Stream ];_dcaa {continue ;};if _fac .PPI <=_ffg .ImageUpperPPI {continue ;};_dadg ,_faaf :=_c .NewXObjectImageFromStream (_fac .Stream );if _faaf !=nil {_e .Log .Debug ("\u0045\u0052\u0052\u004f\u0052\u003a\u0020\u0025\u002b\u0076",_faaf );
continue ;};var _bda imageModifications ;_bda .Scale =_ffg .ImageUpperPPI /_fac .PPI ;if _fac .BitsPerComponent ==1&&_fac .ColorComponents ==1{_dae :=_d .Round (_fac .PPI /_ffg .ImageUpperPPI );_bce :=_a .NextPowerOf2 (uint (_dae ));if _a .InDelta (float64 (_bce ),1/_bda .Scale ,0.3){_bda .Scale =float64 (1)/float64 (_bce );
};if _ ,_gae :=_dadg .Filter .(*_bb .JBIG2Encoder );!_gae {_bda .Encoding =_bb .NewJBIG2Encoder ();};};if _faaf =_eege (_dadg ,_bda );_faaf !=nil {_e .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",_faaf );
continue ;};_bda .Encoding =nil ;if _bbea ,_bfbg :=_bb .GetStream (_fac .Stream .PdfObjectDictionary .Get ("\u0053\u004d\u0061s\u006b"));_bfbg {_bffc ,_fgfe :=_c .NewXObjectImageFromStream (_bbea );if _fgfe !=nil {_e .Log .Debug ("\u0045\u0052\u0052\u004f\u0052\u003a\u0020\u0025\u002b\u0076",_fgfe );
continue ;};if _fgfe =_eege (_bffc ,_bda );_fgfe !=nil {_e .Log .Debug ("\u0045\u0052\u0052\u004f\u0052\u003a\u0020\u0025\u002b\u0076",_fgfe );continue ;};};};return objects ,nil ;};func _ecd (_cc []_bb .PdfObject )(_dcb map[*_bb .PdfObjectStream ]struct{},_fff error ){_dcb =map[*_bb .PdfObjectStream ]struct{}{};
_ega :=map[*_c .PdfFont ]struct{}{};_gbg :=_gcfb (_cc );for _ ,_cb :=range _gbg ._dfda {_dfa ,_gbcc :=_bb .GetDict (_cb .PdfObject );if !_gbcc {continue ;};_dba ,_gbcc :=_bb .GetDict (_dfa .Get ("\u0052e\u0073\u006f\u0075\u0072\u0063\u0065s"));if !_gbcc {continue ;
};_fbb ,_ :=_bdg (_dfa .Get ("\u0043\u006f\u006e\u0074\u0065\u006e\u0074\u0073"));_ab ,_ffc :=_c .NewPdfPageResourcesFromDict (_dba );if _ffc !=nil {return nil ,_ffc ;};_cac :=[]content {{_feac :_fbb ,_dbd :_ab }};_ccc :=_cga (_dfa .Get ("\u0041\u006e\u006e\u006f\u0074\u0073"));
if _ccc !=nil {_cac =append (_cac ,_ccc ...);};for _ ,_bd :=range _cac {_ccg ,_fgf :=_eb .NewFromContents (_bd ._feac ,_bd ._dbd );if _fgf !=nil {return nil ,_fgf ;};_dbg ,_ ,_ ,_fgf :=_ccg .ExtractPageText ();if _fgf !=nil {return nil ,_fgf ;};for _ ,_feg :=range _dbg .Marks ().Elements (){if _feg .Font ==nil {continue ;
};if _ ,_fce :=_ega [_feg .Font ];!_fce {_ega [_feg .Font ]=struct{}{};};};};};_cbg :=map[*_bb .PdfObjectStream ][]*_c .PdfFont {};for _dee :=range _ega {_cce :=_dee .FontDescriptor ();if _cce ==nil ||_cce .FontFile2 ==nil {continue ;};_eada ,_be :=_bb .GetStream (_cce .FontFile2 );
if !_be {continue ;};_cbg [_eada ]=append (_cbg [_eada ],_dee );};for _bgcg :=range _cbg {var _efa []rune ;var _ddb []_bf .GlyphIndex ;for _ ,_ada :=range _cbg [_bgcg ]{switch _gbf :=_ada .Encoder ().(type ){case *_ee .IdentityEncoder :_gde :=_gbf .RegisteredRunes ();
_ffb :=make ([]_bf .GlyphIndex ,len (_gde ));for _age ,_agf :=range _gde {_ffb [_age ]=_bf .GlyphIndex (_agf );};_ddb =append (_ddb ,_ffb ...);case *_ee .TrueTypeFontEncoder :_bfac :=_gbf .RegisteredRunes ();_efa =append (_efa ,_bfac ...);case _ee .SimpleEncoder :_cde :=_gbf .Charcodes ();
for _ ,_fbd :=range _cde {_ce ,_ageg :=_gbf .CharcodeToRune (_fbd );if !_ageg {_e .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",_fbd );
continue ;};_efa =append (_efa ,_ce );};};};_fff =_aee (_bgcg ,_efa ,_ddb );if _fff !=nil {_e .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",_fff );
return nil ,_fff ;};_dcb [_bgcg ]=struct{}{};};return _dcb ,nil ;};
2021-05-31 17:17:31 +00:00
2021-08-13 01:33:42 +00:00
// CombineIdenticalIndirectObjects combines identical indirect objects.
// It implements interface model.Optimizer.
2021-09-23 22:37:42 +00:00
type CombineIdenticalIndirectObjects struct{};func _gcfb (_bab []_bb .PdfObject )objectStructure {_aaca :=objectStructure {};_dfge :=false ;for _ ,_ebg :=range _bab {switch _dbce :=_ebg .(type ){case *_bb .PdfIndirectObject :_ecde ,_bbcg :=_bb .GetDict (_dbce );
if !_bbcg {continue ;};_caee ,_bbcg :=_bb .GetName (_ecde .Get ("\u0054\u0079\u0070\u0065"));if !_bbcg {continue ;};switch _caee .String (){case "\u0043a\u0074\u0061\u006c\u006f\u0067":_aaca ._fbde =_ecde ;_dfge =true ;};};if _dfge {break ;};};if !_dfge {return _aaca ;
};_gcaa ,_efe :=_bb .GetDict (_aaca ._fbde .Get ("\u0050\u0061\u0067e\u0073"));if !_efe {return _aaca ;};_aaca ._eedd =_gcaa ;_fbdf ,_efe :=_bb .GetArray (_gcaa .Get ("\u004b\u0069\u0064\u0073"));if !_efe {return _aaca ;};for _ ,_bccf :=range _fbdf .Elements (){_adea ,_edc :=_bb .GetIndirect (_bccf );
if !_edc {break ;};_aaca ._dfda =append (_aaca ._dfda ,_adea );};return _aaca ;};
2021-05-11 00:01:27 +00:00
2021-09-23 22:37:42 +00:00
// 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 ;
};
2021-04-23 20:28:14 +00:00
2021-09-23 22:37:42 +00:00
// Optimize optimizes PDF objects to decrease PDF size.
func (_aabf *CombineDuplicateDirectObjects )Optimize (objects []_bb .PdfObject )(_ffce []_bb .PdfObject ,_acae error ){_aaaa (objects );_cdd :=make (map[string ][]*_bb .PdfObjectDictionary );var _bbc func (_cfb *_bb .PdfObjectDictionary );_bbc =func (_bfgg *_bb .PdfObjectDictionary ){for _ ,_dge :=range _bfgg .Keys (){_dac :=_bfgg .Get (_dge );
if _ecff ,_dgd :=_dac .(*_bb .PdfObjectDictionary );_dgd {_fdg :=_eg .New ();_fdg .Write ([]byte (_ecff .WriteString ()));_fee :=string (_fdg .Sum (nil ));_cdd [_fee ]=append (_cdd [_fee ],_ecff );_bbc (_ecff );};};};for _ ,_aea :=range objects {_bbeb ,_aaa :=_aea .(*_bb .PdfIndirectObject );
if !_aaa {continue ;};if _dad ,_fef :=_bbeb .PdfObject .(*_bb .PdfObjectDictionary );_fef {_bbc (_dad );};};_cbe :=make ([]_bb .PdfObject ,0,len (_cdd ));_cdf :=make (map[_bb .PdfObject ]_bb .PdfObject );for _ ,_debb :=range _cdd {if len (_debb )< 2{continue ;
};_bbb :=_bb .MakeDict ();_bbb .Merge (_debb [0]);_adb :=_bb .MakeIndirectObject (_bbb );_cbe =append (_cbe ,_adb );for _ebcb :=0;_ebcb < len (_debb );_ebcb ++{_bed :=_debb [_ebcb ];_cdf [_bed ]=_adb ;};};_ffce =make ([]_bb .PdfObject ,len (objects ));
copy (_ffce ,objects );_ffce =append (_cbe ,_ffce ...);_cbef (_ffce ,_cdf );return _ffce ,nil ;};type imageInfo struct{BitsPerComponent int ;ColorComponents int ;Width int ;Height int ;Stream *_bb .PdfObjectStream ;PPI float64 ;};func _cga (_bgg _bb .PdfObject )[]content {if _bgg ==nil {return nil ;
};_eee ,_acab :=_bb .GetArray (_bgg );if !_acab {_e .Log .Debug ("\u0041\u006e\u006e\u006fts\u0020\u006e\u006f\u0074\u0020\u0061\u006e\u0020\u0061\u0072\u0072\u0061\u0079");return nil ;};var _cae []content ;for _ ,_aed :=range _eee .Elements (){_fdd ,_fec :=_bb .GetDict (_aed );
if !_fec {_e .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 ;};_ffe ,_fec :=_bb .GetDict (_fdd .Get ("\u0041\u0050"));
if !_fec {_e .Log .Debug ("\u004e\u006f\u0020\u0041P \u0065\u006e\u0074\u0072\u0079\u0020\u002d\u0020\u0073\u006b\u0069\u0070\u0070\u0069n\u0067");continue ;};_afe :=_bb .TraceToDirectObject (_ffe .Get ("\u004e"));if _afe ==nil {_e .Log .Debug ("N\u006f\u0020\u004e\u0020en\u0074r\u0079\u0020\u002d\u0020\u0073k\u0069\u0070\u0070\u0069\u006e\u0067");
continue ;};var _aeed *_bb .PdfObjectStream ;switch _fcb :=_afe .(type ){case *_bb .PdfObjectDictionary :_gba ,_bef :=_bb .GetName (_fdd .Get ("\u0041\u0053"));if !_bef {_e .Log .Debug ("\u004e\u006f\u0020\u0041S \u0065\u006e\u0074\u0072\u0079\u0020\u002d\u0020\u0073\u006b\u0069\u0070\u0070\u0069n\u0067");
continue ;};_aeed ,_bef =_bb .GetStream (_fcb .Get (*_gba ));if !_bef {_e .Log .Debug ("\u0046o\u0072\u006d\u0020\u006eo\u0074\u0020\u0066\u006f\u0075n\u0064 \u002d \u0073\u006b\u0069\u0070\u0070\u0069\u006eg");continue ;};case *_bb .PdfObjectStream :_aeed =_fcb ;
};if _aeed ==nil {_e .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 ;};_aecb ,_ecg :=_c .NewXObjectFormFromStream (_aeed );
if _ecg !=nil {_e .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",_ecg );continue ;};_fgg ,_ecg :=_aecb .GetContentStream ();
if _ecg !=nil {_e .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",_ecg );continue ;};_cae =append (_cae ,content {_feac :string (_fgg ),_dbd :_aecb .Resources });
};return _cae ;};func _aaaa (_bbbb []_bb .PdfObject ){for _dbgc ,_dcdb :=range _bbbb {switch _bccd :=_dcdb .(type ){case *_bb .PdfIndirectObject :_bccd .ObjectNumber =int64 (_dbgc +1);_bccd .GenerationNumber =0;case *_bb .PdfObjectStream :_bccd .ObjectNumber =int64 (_dbgc +1);
_bccd .GenerationNumber =0;case *_bb .PdfObjectStreams :_bccd .ObjectNumber =int64 (_dbgc +1);_bccd .GenerationNumber =0;};};};func _eege (_dgag *_c .XObjectImage ,_abae imageModifications )error {_fcdf ,_eba :=_dgag .ToImage ();if _eba !=nil {return _eba ;
};if _abae .Scale !=0{_fcdf ,_eba =_eaaa (_fcdf ,_abae .Scale );if _eba !=nil {return _eba ;};};if _abae .Encoding !=nil {_dgag .Filter =_abae .Encoding ;};_dgag .Decode =nil ;switch _egddc :=_dgag .Filter .(type ){case *_bb .FlateEncoder :if _egddc .Predictor !=1&&_egddc .Predictor !=11{_egddc .Predictor =1;
};};if _eba =_dgag .SetImage (_fcdf ,nil );_eba !=nil {_e .Log .Debug ("\u0045\u0072\u0072or\u0020\u0073\u0065\u0074\u0074\u0069\u006e\u0067\u0020\u0069\u006d\u0061\u0067\u0065\u003a\u0020\u0025\u0076",_eba );return _eba ;};_dgag .ToPdfObject ();return nil ;
};func _gd (_gf *_g .ContentStreamOperations )*_g .ContentStreamOperations {if _gf ==nil {return nil ;};_da :=_g .ContentStreamOperations {};for _ ,_gdc :=range *_gf {switch _gdc .Operand {case "\u0042\u0044\u0043","\u0042\u004d\u0043","\u0045\u004d\u0043":continue ;
case "\u0054\u006d":if len (_gdc .Params )==6{if _gdf ,_ge :=_bb .GetNumbersAsFloat (_gdc .Params );_ge ==nil {if _gdf [0]==1&&_gdf [1]==0&&_gdf [2]==0&&_gdf [3]==1{_gdc =&_g .ContentStreamOperation {Params :[]_bb .PdfObject {_gdc .Params [4],_gdc .Params [5]},Operand :"\u0054\u0064"};
};};};};_da =append (_da ,_gdc );};return &_da ;};
2020-10-05 19:28:24 +00:00
2021-08-13 01:33:42 +00:00
// Optimize optimizes PDF objects to decrease PDF size.
2021-09-23 22:37:42 +00:00
func (_agc *CompressStreams )Optimize (objects []_bb .PdfObject )(_ebf []_bb .PdfObject ,_fecg error ){_ebf =make ([]_bb .PdfObject ,len (objects ));copy (_ebf ,objects );for _ ,_gff :=range objects {_dcafb ,_ffba :=_bb .GetStream (_gff );if !_ffba {continue ;
};if _bec :=_dcafb .Get ("\u0046\u0069\u006c\u0074\u0065\u0072");_bec !=nil {if _ ,_agg :=_bb .GetName (_bec );_agg {continue ;};if _acf ,_faf :=_bb .GetArray (_bec );_faf &&_acf .Len ()> 0{continue ;};};_gedf :=_bb .NewFlateEncoder ();var _aafa []byte ;
_aafa ,_fecg =_gedf .EncodeBytes (_dcafb .Stream );if _fecg !=nil {return _ebf ,_fecg ;};_gdg :=_gedf .MakeStreamDict ();if len (_aafa )+len (_gdg .WriteString ())< len (_dcafb .Stream ){_dcafb .Stream =_aafa ;_dcafb .PdfObjectDictionary .Merge (_gdg );
_dcafb .PdfObjectDictionary .Set ("\u004c\u0065\u006e\u0067\u0074\u0068",_bb .MakeInteger (int64 (len (_dcafb .Stream ))));};};return _ebf ,nil ;};type imageModifications struct{Scale float64 ;Encoding _bb .StreamEncoder ;};func _gcad (_eae []_bb .PdfObject )[]*imageInfo {_aedc :=_bb .PdfObjectName ("\u0053u\u0062\u0074\u0079\u0070\u0065");
_cda :=make (map[*_bb .PdfObjectStream ]struct{});var _def []*imageInfo ;for _ ,_eaa :=range _eae {_dga ,_adbd :=_bb .GetStream (_eaa );if !_adbd {continue ;};if _ ,_abgf :=_cda [_dga ];_abgf {continue ;};_cda [_dga ]=struct{}{};_cee :=_dga .PdfObjectDictionary .Get (_aedc );
_aaea ,_adbd :=_bb .GetName (_cee );if !_adbd ||string (*_aaea )!="\u0049\u006d\u0061g\u0065"{continue ;};_gee :=&imageInfo {Stream :_dga ,BitsPerComponent :8};if _ddf ,_dfd :=_bb .GetIntVal (_dga .Get ("\u0042\u0069t\u0073\u0050\u0065r\u0043\u006f\u006d\u0070\u006f\u006e\u0065\u006e\u0074"));
_dfd {_gee .BitsPerComponent =_ddf ;};if _eaad ,_cbc :=_bb .GetIntVal (_dga .Get ("\u0057\u0069\u0064t\u0068"));_cbc {_gee .Width =_eaad ;};if _ggd ,_abb :=_bb .GetIntVal (_dga .Get ("\u0048\u0065\u0069\u0067\u0068\u0074"));_abb {_gee .Height =_ggd ;};
_cedg ,_gef :=_c .NewPdfColorspaceFromPdfObject (_dga .Get ("\u0043\u006f\u006c\u006f\u0072\u0053\u0070\u0061\u0063\u0065"));if _gef !=nil {_e .Log .Debug ("\u0045R\u0052\u004f\u0052\u003a\u0020\u0025v",_gef );continue ;};if _cedg ==nil {_bad ,_ggb :=_bb .GetName (_dga .Get ("\u0046\u0069\u006c\u0074\u0065\u0072"));
if _ggb {switch _bad .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":_cedg =_c .NewPdfColorspaceDeviceGray ();_gee .BitsPerComponent =1;};
};};switch _acbc :=_cedg .(type ){case *_c .PdfColorspaceDeviceRGB :_gee .ColorComponents =3;case *_c .PdfColorspaceDeviceGray :_gee .ColorComponents =1;default:_e .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",_acbc );
continue ;};_def =append (_def ,_gee );};return _def ;};func _ec (_bfe *_bb .PdfObjectStream )error {_ecf ,_ac :=_bb .DecodeStream (_bfe );if _ac !=nil {return _ac ;};_dc :=_g .NewContentStreamParser (string (_ecf ));_df ,_ac :=_dc .Parse ();if _ac !=nil {return _ac ;
};_df =_gd (_df );_ae :=_df .Bytes ();if len (_ae )>=len (_ecf ){return nil ;};_gc ,_ac :=_bb .MakeStream (_df .Bytes (),_bb .NewFlateEncoder ());if _ac !=nil {return _ac ;};_bfe .Stream =_gc .Stream ;_bfe .Merge (_gc .PdfObjectDictionary );return nil ;
};
// CompressStreams compresses uncompressed streams.
// It implements interface model.Optimizer.
type CompressStreams struct{};type objectStructure struct{_fbde *_bb .PdfObjectDictionary ;_eedd *_bb .PdfObjectDictionary ;_dfda []*_bb .PdfIndirectObject ;};
2021-08-13 01:33:42 +00:00
// CombineDuplicateDirectObjects combines duplicated direct objects by its data hash.
2021-06-21 14:01:56 +00:00
// It implements interface model.Optimizer.
2021-09-23 22:37:42 +00:00
type CombineDuplicateDirectObjects struct{};
2021-02-22 02:29:48 +00:00
2021-09-23 22:37:42 +00:00
// Optimize optimizes PDF objects to decrease PDF size.
func (_cebd *Image )Optimize (objects []_bb .PdfObject )(_efb []_bb .PdfObject ,_cgaf error ){if _cebd .ImageQuality <=0{return objects ,nil ;};_cacg :=_gcad (objects );if len (_cacg )==0{return objects ,nil ;};_abaa :=make (map[_bb .PdfObject ]_bb .PdfObject );
_gfd :=make (map[_bb .PdfObject ]struct{});for _ ,_gge :=range _cacg {_dfca :=_gge .Stream .Get ("\u0053\u004d\u0061s\u006b");_gfd [_dfca ]=struct{}{};};for _aad ,_cff :=range _cacg {_ecbgb :=_cff .Stream ;if _ ,_gged :=_gfd [_ecbgb ];_gged {continue ;
};_gdca ,_ege :=_c .NewXObjectImageFromStream (_ecbgb );if _ege !=nil {_e .Log .Debug ("\u0045\u0052\u0052\u004f\u0052\u003a\u0020\u0025\u002b\u0076",_ege );continue ;};switch _gdca .Filter .(type ){case *_bb .JBIG2Encoder :continue ;case *_bb .CCITTFaxEncoder :continue ;
};_ecad ,_ege :=_gdca .ToImage ();if _ege !=nil {_e .Log .Debug ("\u0045\u0052\u0052\u004f\u0052\u003a\u0020\u0025\u002b\u0076",_ege );continue ;};_fecd :=_bb .NewDCTEncoder ();_fecd .ColorComponents =_ecad .ColorComponents ;_fecd .Quality =_cebd .ImageQuality ;
_fecd .BitsPerComponent =_cff .BitsPerComponent ;_fecd .Width =_cff .Width ;_fecd .Height =_cff .Height ;_fcg ,_ege :=_fecd .EncodeBytes (_ecad .Data );if _ege !=nil {_e .Log .Debug ("\u0045\u0052\u0052\u004f\u0052\u003a\u0020\u0025\u002b\u0076",_ege );
continue ;};var _ecfc _bb .StreamEncoder ;_ecfc =_fecd ;{_aaee :=_bb .NewFlateEncoder ();_fca :=_bb .NewMultiEncoder ();_fca .AddEncoder (_aaee );_fca .AddEncoder (_fecd );_beda ,_bfge :=_fca .EncodeBytes (_ecad .Data );if _bfge !=nil {_e .Log .Debug ("\u0045\u0052\u0052\u004f\u0052\u003a\u0020\u0025\u002b\u0076",_bfge );
continue ;};if len (_beda )< len (_fcg ){_e .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 (_fcg ),len (_beda ),len (_ecbgb .Stream ));
_fcg =_beda ;_ecfc =_fca ;};};_fgbf :=len (_ecbgb .Stream );if _fgbf < len (_fcg ){continue ;};_cec :=&_bb .PdfObjectStream {Stream :_fcg };_cec .PdfObjectReference =_ecbgb .PdfObjectReference ;_cec .PdfObjectDictionary =_bb .MakeDict ();_cec .Merge (_ecbgb .PdfObjectDictionary );
_cec .Merge (_ecfc .MakeStreamDict ());_cec .Set ("\u004c\u0065\u006e\u0067\u0074\u0068",_bb .MakeInteger (int64 (len (_fcg ))));_abaa [_ecbgb ]=_cec ;_cacg [_aad ].Stream =_cec ;};_efb =make ([]_bb .PdfObject ,len (objects ));copy (_efb ,objects );_cbef (_efb ,_abaa );
return _efb ,nil ;};
2021-08-13 01:33:42 +00:00
2021-09-23 22:37:42 +00:00
// Image optimizes images by rewrite images into JPEG format with quality equals to ImageQuality.
2021-08-13 01:33:42 +00:00
// TODO(a5i): Add support for inline images.
// It implements interface model.Optimizer.
2021-09-23 22:37:42 +00:00
type Image struct{ImageQuality int ;};func _bdg (_ffbf _bb .PdfObject )(_dff string ,_dacfd []_bb .PdfObject ){var _gaf _gb .Buffer ;switch _fdbb :=_ffbf .(type ){case *_bb .PdfIndirectObject :_dacfd =append (_dacfd ,_fdbb );_ffbf =_fdbb .PdfObject ;};
switch _edg :=_ffbf .(type ){case *_bb .PdfObjectStream :if _feb ,_ddfe :=_bb .DecodeStream (_edg );_ddfe ==nil {_gaf .Write (_feb );_dacfd =append (_dacfd ,_edg );};case *_bb .PdfObjectArray :for _ ,_ebcg :=range _edg .Elements (){switch _ggdg :=_ebcg .(type ){case *_bb .PdfObjectStream :if _dcag ,_dec :=_bb .DecodeStream (_ggdg );
_dec ==nil {_gaf .Write (_dcag );_dacfd =append (_dacfd ,_ggdg );};};};};return _gaf .String (),_dacfd ;};
2021-08-13 01:33:42 +00:00
// Optimize optimizes PDF objects to decrease PDF size.
2021-09-23 22:37:42 +00:00
func (_acc *CleanContentstream )Optimize (objects []_bb .PdfObject )(_bfg []_bb .PdfObject ,_cf error ){_gcd :=map[*_bb .PdfObjectStream ]struct{}{};var _gda []*_bb .PdfObjectStream ;_bcc :=func (_aef *_bb .PdfObjectStream ){if _ ,_ff :=_gcd [_aef ];!_ff {_gcd [_aef ]=struct{}{};
_gda =append (_gda ,_aef );};};_dfc :=map[_bb .PdfObject ]bool {};_egd :=map[_bb .PdfObject ]bool {};for _ ,_acb :=range objects {switch _fg :=_acb .(type ){case *_bb .PdfIndirectObject :switch _ecb :=_fg .PdfObject .(type ){case *_bb .PdfObjectDictionary :if _bbe ,_dcf :=_bb .GetName (_ecb .Get ("\u0054\u0079\u0070\u0065"));
!_dcf ||_bbe .String ()!="\u0050\u0061\u0067\u0065"{continue ;};if _fd ,_bgc :=_bb .GetStream (_ecb .Get ("\u0043\u006f\u006e\u0074\u0065\u006e\u0074\u0073"));_bgc {_bcc (_fd );}else if _aab ,_ead :=_bb .GetArray (_ecb .Get ("\u0043\u006f\u006e\u0074\u0065\u006e\u0074\u0073"));
_ead {var _aaf []*_bb .PdfObjectStream ;for _ ,_bfa :=range _aab .Elements (){if _efc ,_ffa :=_bb .GetStream (_bfa );_ffa {_aaf =append (_aaf ,_efc );};};if len (_aaf )> 0{var _gfc _gb .Buffer ;for _ ,_dd :=range _aaf {if _aca ,_af :=_bb .DecodeStream (_dd );
_af ==nil {_gfc .Write (_aca );};_dfc [_dd ]=true ;};_fgb ,_db :=_bb .MakeStream (_gfc .Bytes (),_bb .NewFlateEncoder ());if _db !=nil {return nil ,_db ;};_egd [_fgb ]=true ;_ecb .Set ("\u0043\u006f\u006e\u0074\u0065\u006e\u0074\u0073",_fgb );_bcc (_fgb );
};};};case *_bb .PdfObjectStream :if _ca ,_ba :=_bb .GetName (_fg .Get ("\u0054\u0079\u0070\u0065"));!_ba ||_ca .String ()!="\u0058O\u0062\u006a\u0065\u0063\u0074"{continue ;};if _cfg ,_ebc :=_bb .GetName (_fg .Get ("\u0053u\u0062\u0074\u0079\u0070\u0065"));
!_ebc ||_cfg .String ()!="\u0046\u006f\u0072\u006d"{continue ;};_bcc (_fg );};};for _ ,_bbd :=range _gda {_cf =_ec (_bbd );if _cf !=nil {return nil ,_cf ;};};_bfg =nil ;for _ ,_gbcb :=range objects {if _dfc [_gbcb ]{continue ;};_bfg =append (_bfg ,_gbcb );
};for _dg :=range _egd {_bfg =append (_bfg ,_dg );};return _bfg ,nil ;};
// Append appends optimizers to the chain.
func (_de *Chain )Append (optimizers ..._c .Optimizer ){_de ._ef =append (_de ._ef ,optimizers ...)};
2021-04-17 13:46:54 +00:00
2021-07-30 00:21:16 +00:00
// Optimize optimizes PDF objects to decrease PDF size.
2021-09-23 22:37:42 +00:00
func (_bfgf *CleanFonts )Optimize (objects []_bb .PdfObject )(_eeg []_bb .PdfObject ,_agd error ){var _bfb map[*_bb .PdfObjectStream ]struct{};if _bfgf .Subset {var _ccec error ;_bfb ,_ccec =_ecd (objects );if _ccec !=nil {_e .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",_ccec );
return nil ,_ccec ;};};for _ ,_cbd :=range objects {_acd ,_ecbg :=_bb .GetStream (_cbd );if !_ecbg {continue ;};if _ ,_fdc :=_bfb [_acd ];_fdc {continue ;};_dcaf ,_abd :=_bb .NewEncoderFromStream (_acd );if _abd !=nil {_e .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",_abd );
continue ;};_cgf ,_abd :=_dcaf .DecodeStream (_acd );if _abd !=nil {_e .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",_abd );
continue ;};if len (_cgf )< 4{continue ;};_bfbc :=string (_cgf [:4]);if _bfbc =="\u004f\u0054\u0054\u004f"{continue ;};if _bfbc !="\u0000\u0001\u0000\u0000"&&_bfbc !="\u0074\u0072\u0075\u0065"{continue ;};_daa ,_abd :=_bf .Parse (_gb .NewReader (_cgf ));
if _abd !=nil {_e .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",_abd );continue ;};_abd =_daa .Optimize ();
if _abd !=nil {_e .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",_abd );continue ;};var _faa _gb .Buffer ;_abd =_daa .Write (&_faa );
if _abd !=nil {_e .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",_abd );continue ;};if _faa .Len ()> len (_cgf ){_e .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 ;};_fea ,_abd :=_bb .MakeStream (_faa .Bytes (),_bb .NewFlateEncoder ());if _abd !=nil {continue ;};*_acd =*_fea ;_acd .Set ("\u004ce\u006e\u0067\u0074\u0068\u0031",_bb .MakeInteger (int64 (_faa .Len ())));};return objects ,nil ;};
2021-08-13 01:33:42 +00:00
2021-09-23 22:37:42 +00:00
// New creates a optimizers chain from options.
func New (options Options )*Chain {_bead :=new (Chain );if options .CleanFonts ||options .SubsetFonts {_bead .Append (&CleanFonts {Subset :options .SubsetFonts });};if options .CleanContentstream {_bead .Append (new (CleanContentstream ));};if options .ImageUpperPPI > 0{_abf :=new (ImagePPI );
_abf .ImageUpperPPI =options .ImageUpperPPI ;_bead .Append (_abf );};if options .ImageQuality > 0{_cdff :=new (Image );_cdff .ImageQuality =options .ImageQuality ;_bead .Append (_cdff );};if options .CombineDuplicateDirectObjects {_bead .Append (new (CombineDuplicateDirectObjects ));
};if options .CombineDuplicateStreams {_bead .Append (new (CombineDuplicateStreams ));};if options .CombineIdenticalIndirectObjects {_bead .Append (new (CombineIdenticalIndirectObjects ));};if options .UseObjectStreams {_bead .Append (new (ObjectStreams ));
};if options .CompressStreams {_bead .Append (new (CompressStreams ));};return _bead ;};
// CombineDuplicateStreams combines duplicated streams by its data hash.
// It implements interface model.Optimizer.
type CombineDuplicateStreams struct{};func _cbef (_efgg []_bb .PdfObject ,_cbcc map[_bb .PdfObject ]_bb .PdfObject ){if len (_cbcc )==0{return ;};for _dgf ,_eafec :=range _efgg {if _dfed ,_ceg :=_cbcc [_eafec ];_ceg {_efgg [_dgf ]=_dfed ;continue ;};_cbcc [_eafec ]=_eafec ;
switch _dfcc :=_eafec .(type ){case *_bb .PdfObjectArray :_ebdb :=make ([]_bb .PdfObject ,_dfcc .Len ());copy (_ebdb ,_dfcc .Elements ());_cbef (_ebdb ,_cbcc );for _bbff ,_adae :=range _ebdb {_dfcc .Set (_bbff ,_adae );};case *_bb .PdfObjectStreams :_cbef (_dfcc .Elements (),_cbcc );
case *_bb .PdfObjectStream :_aadd :=[]_bb .PdfObject {_dfcc .PdfObjectDictionary };_cbef (_aadd ,_cbcc );_dfcc .PdfObjectDictionary =_aadd [0].(*_bb .PdfObjectDictionary );case *_bb .PdfObjectDictionary :_fbce :=_dfcc .Keys ();_dacf :=make ([]_bb .PdfObject ,len (_fbce ));
for _dged ,_caeb :=range _fbce {_dacf [_dged ]=_dfcc .Get (_caeb );};_cbef (_dacf ,_cbcc );for _affa ,_bgfd :=range _fbce {_dfcc .Set (_bgfd ,_dacf [_affa ]);};case *_bb .PdfIndirectObject :_ddbg :=[]_bb .PdfObject {_dfcc .PdfObject };_cbef (_ddbg ,_cbcc );
_dfcc .PdfObject =_ddbg [0];};};};func _eaaa (_cfbb *_c .Image ,_ccee float64 )(*_c .Image ,error ){_gebe ,_ddd :=_cfbb .ToGoImage ();if _ddd !=nil {return nil ,_ddd ;};var _eedf _a .Image ;_dadb ,_bggf :=_gebe .(*_a .Monochrome );if _bggf {if _ddd =_dadb .ResolveDecode ();
_ddd !=nil {return nil ,_ddd ;};_eedf ,_ddd =_dadb .Scale (_ccee );if _ddd !=nil {return nil ,_ddd ;};}else {_gcf :=int (_d .RoundToEven (float64 (_cfbb .Width )*_ccee ));_ece :=int (_d .RoundToEven (float64 (_cfbb .Height )*_ccee ));_eedf ,_ddd =_a .NewImage (_gcf ,_ece ,int (_cfbb .BitsPerComponent ),_cfbb .ColorComponents ,nil ,nil ,nil );
if _ddd !=nil {return nil ,_ddd ;};_f .CatmullRom .Scale (_eedf ,_eedf .Bounds (),_gebe ,_gebe .Bounds (),_f .Over ,&_f .Options {});};_gdd :=_eedf .Base ();_adg :=&_c .Image {Width :int64 (_gdd .Width ),Height :int64 (_gdd .Height ),BitsPerComponent :int64 (_gdd .BitsPerComponent ),ColorComponents :_gdd .ColorComponents ,Data :_gdd .Data };
_adg .SetDecode (_gdd .Decode );_adg .SetAlpha (_gdd .Alpha );return _adg ,nil ;};
2021-08-13 01:33:42 +00:00
// 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.
2021-09-23 22:37:42 +00:00
Subset bool ;};
// Optimize optimizes PDF objects to decrease PDF size.
func (_ad *Chain )Optimize (objects []_bb .PdfObject )(_ea []_bb .PdfObject ,_fc error ){_bc :=objects ;for _ ,_bg :=range _ad ._ef {_fe ,_fb :=_bg .Optimize (_bc );if _fb !=nil {_e .Log .Debug ("\u0045\u0052\u0052OR\u0020\u004f\u0070\u0074\u0069\u006d\u0069\u007a\u0061\u0074\u0069\u006f\u006e\u003a\u0020\u0025\u002b\u0076",_fb );
continue ;};_bc =_fe ;};return _bc ,nil ;};
// Optimize optimizes PDF objects to decrease PDF size.
func (_cbb *CombineIdenticalIndirectObjects )Optimize (objects []_bb .PdfObject )(_ebd []_bb .PdfObject ,_fbg error ){_aaaa (objects );_dfeb :=make (map[_bb .PdfObject ]_bb .PdfObject );_cacf :=make (map[_bb .PdfObject ]struct{});_ecc :=make (map[string ][]*_bb .PdfIndirectObject );
for _ ,_ddbe :=range objects {_cab ,_aeg :=_ddbe .(*_bb .PdfIndirectObject );if !_aeg {continue ;};if _aba ,_bac :=_cab .PdfObject .(*_bb .PdfObjectDictionary );_bac {if _dda ,_fcd :=_aba .Get ("\u0054\u0079\u0070\u0065").(*_bb .PdfObjectName );_fcd &&*_dda =="\u0050\u0061\u0067\u0065"{continue ;
};_dgde :=_eg .New ();_dgde .Write ([]byte (_aba .WriteString ()));_cbgc :=string (_dgde .Sum (nil ));_ecc [_cbgc ]=append (_ecc [_cbgc ],_cab );};};for _ ,_aag :=range _ecc {if len (_aag )< 2{continue ;};_bgd :=_aag [0];for _bba :=1;_bba < len (_aag );
_bba ++{_cbge :=_aag [_bba ];_dfeb [_cbge ]=_bgd ;_cacf [_cbge ]=struct{}{};};};_ebd =make ([]_bb .PdfObject ,0,len (objects )-len (_cacf ));for _ ,_gebg :=range objects {if _ ,_cbga :=_cacf [_gebg ];_cbga {continue ;};_ebd =append (_ebd ,_gebg );};_cbef (_ebd ,_dfeb );
return _ebd ,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 ;};