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/
|
|
|
|
|
2023-04-06 19:57:40 +00:00
|
|
|
package optimize ;import (_e "bytes";_dd "crypto/md5";_f "errors";_d "github.com/unidoc/unipdf/v3/common";_ge "github.com/unidoc/unipdf/v3/contentstream";_ga "github.com/unidoc/unipdf/v3/core";_cg "github.com/unidoc/unipdf/v3/extractor";_ddc "github.com/unidoc/unipdf/v3/internal/imageutil";
|
|
|
|
_b "github.com/unidoc/unipdf/v3/internal/textencoding";_cf "github.com/unidoc/unipdf/v3/model";_gd "github.com/unidoc/unitype";_ca "golang.org/x/image/draw";_g "math";);
|
|
|
|
|
|
|
|
// Append appends optimizers to the chain.
|
|
|
|
func (_ff *Chain )Append (optimizers ..._cf .Optimizer ){_ff ._bc =append (_ff ._bc ,optimizers ...)};
|
2022-09-10 15:35:04 +00:00
|
|
|
|
2022-10-27 19:04:58 +00:00
|
|
|
// Optimize optimizes PDF objects to decrease PDF size.
|
2023-04-06 19:57:40 +00:00
|
|
|
func (_dbe *CleanFonts )Optimize (objects []_ga .PdfObject )(_dgb []_ga .PdfObject ,_bab error ){var _fgab map[*_ga .PdfObjectStream ]struct{};if _dbe .Subset {var _ceeg error ;_fgab ,_ceeg =_gfg (objects );if _ceeg !=nil {_d .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",_ceeg );
|
|
|
|
return nil ,_ceeg ;};};for _ ,_ddg :=range objects {_aac ,_fa :=_ga .GetStream (_ddg );if !_fa {continue ;};if _ ,_dfd :=_fgab [_aac ];_dfd {continue ;};_ffd ,_afe :=_ga .NewEncoderFromStream (_aac );if _afe !=nil {_d .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",_afe );
|
|
|
|
continue ;};_efd ,_afe :=_ffd .DecodeStream (_aac );if _afe !=nil {_d .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",_afe );
|
|
|
|
continue ;};if len (_efd )< 4{continue ;};_gaa :=string (_efd [:4]);if _gaa =="\u004f\u0054\u0054\u004f"{continue ;};if _gaa !="\u0000\u0001\u0000\u0000"&&_gaa !="\u0074\u0072\u0075\u0065"{continue ;};_adb ,_afe :=_gd .Parse (_e .NewReader (_efd ));if _afe !=nil {_d .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",_afe );
|
|
|
|
continue ;};_afe =_adb .Optimize ();if _afe !=nil {_d .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",_afe );continue ;};var _ab _e .Buffer ;
|
|
|
|
_afe =_adb .Write (&_ab );if _afe !=nil {_d .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",_afe );continue ;
|
|
|
|
};if _ab .Len ()> len (_efd ){_d .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 ;};_cb ,_afe :=_ga .MakeStream (_ab .Bytes (),_ga .NewFlateEncoder ());if _afe !=nil {continue ;};*_aac =*_cb ;_aac .Set ("\u004ce\u006e\u0067\u0074\u0068\u0031",_ga .MakeInteger (int64 (_ab .Len ())));};return objects ,nil ;};
|
2022-09-10 15:35:04 +00:00
|
|
|
|
2023-02-07 17:17:49 +00:00
|
|
|
// Optimize optimizes PDF objects to decrease PDF size.
|
2023-04-06 19:57:40 +00:00
|
|
|
func (_dgg *CleanContentstream )Optimize (objects []_ga .PdfObject )(_fb []_ga .PdfObject ,_eb error ){_ccg :=map[*_ga .PdfObjectStream ]struct{}{};var _ffa []*_ga .PdfObjectStream ;_bad :=func (_bf *_ga .PdfObjectStream ){if _ ,_eeg :=_ccg [_bf ];!_eeg {_ccg [_bf ]=struct{}{};
|
|
|
|
_ffa =append (_ffa ,_bf );};};_bb :=map[_ga .PdfObject ]bool {};_eg :=map[_ga .PdfObject ]bool {};for _ ,_bff :=range objects {switch _eab :=_bff .(type ){case *_ga .PdfIndirectObject :switch _aca :=_eab .PdfObject .(type ){case *_ga .PdfObjectDictionary :if _ddb ,_ccc :=_ga .GetName (_aca .Get ("\u0054\u0079\u0070\u0065"));
|
|
|
|
!_ccc ||_ddb .String ()!="\u0050\u0061\u0067\u0065"{continue ;};if _eea ,_gcf :=_ga .GetStream (_aca .Get ("\u0043\u006f\u006e\u0074\u0065\u006e\u0074\u0073"));_gcf {_bad (_eea );}else if _dgc ,_bade :=_ga .GetArray (_aca .Get ("\u0043\u006f\u006e\u0074\u0065\u006e\u0074\u0073"));
|
|
|
|
_bade {var _ae []*_ga .PdfObjectStream ;for _ ,_ef :=range _dgc .Elements (){if _cggd ,_bca :=_ga .GetStream (_ef );_bca {_ae =append (_ae ,_cggd );};};if len (_ae )> 0{var _ebe _e .Buffer ;for _ ,_ebf :=range _ae {if _fbb ,_ace :=_ga .DecodeStream (_ebf );
|
|
|
|
_ace ==nil {_ebe .Write (_fbb );};_bb [_ebf ]=true ;};_fe ,_aa :=_ga .MakeStream (_ebe .Bytes (),_ga .NewFlateEncoder ());if _aa !=nil {return nil ,_aa ;};_eg [_fe ]=true ;_aca .Set ("\u0043\u006f\u006e\u0074\u0065\u006e\u0074\u0073",_fe );_bad (_fe );
|
|
|
|
};};};case *_ga .PdfObjectStream :if _be ,_de :=_ga .GetName (_eab .Get ("\u0054\u0079\u0070\u0065"));!_de ||_be .String ()!="\u0058O\u0062\u006a\u0065\u0063\u0074"{continue ;};if _cae ,_caee :=_ga .GetName (_eab .Get ("\u0053u\u0062\u0074\u0079\u0070\u0065"));
|
|
|
|
!_caee ||_cae .String ()!="\u0046\u006f\u0072\u006d"{continue ;};_bad (_eab );};};for _ ,_bbd :=range _ffa {_eb =_fc (_bbd );if _eb !=nil {return nil ,_eb ;};};_fb =nil ;for _ ,_acd :=range objects {if _bb [_acd ]{continue ;};_fb =append (_fb ,_acd );};
|
|
|
|
for _ce :=range _eg {_fb =append (_fb ,_ce );};return _fb ,nil ;};
|
2022-09-10 15:35:04 +00:00
|
|
|
|
2023-04-06 19:57:40 +00:00
|
|
|
// Chain allows to use sequence of optimizers.
|
|
|
|
// It implements interface model.Optimizer.
|
|
|
|
type Chain struct{_bc []_cf .Optimizer };
|
2023-01-08 22:34:27 +00:00
|
|
|
|
2023-04-06 19:57:40 +00:00
|
|
|
// 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 _deb (_fbed _ga .PdfObject )[]content {if _fbed ==nil {return nil ;};_gac ,_ecd :=_ga .GetArray (_fbed );if !_ecd {_d .Log .Debug ("\u0041\u006e\u006e\u006fts\u0020\u006e\u006f\u0074\u0020\u0061\u006e\u0020\u0061\u0072\u0072\u0061\u0079");
|
|
|
|
return nil ;};var _bed []content ;for _ ,_ebfd :=range _gac .Elements (){_cec ,_cbf :=_ga .GetDict (_ebfd );if !_cbf {_d .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 ;};_ccga ,_cbf :=_ga .GetDict (_cec .Get ("\u0041\u0050"));if !_cbf {_d .Log .Debug ("\u004e\u006f\u0020\u0041P \u0065\u006e\u0074\u0072\u0079\u0020\u002d\u0020\u0073\u006b\u0069\u0070\u0070\u0069n\u0067");continue ;};_eff :=_ga .TraceToDirectObject (_ccga .Get ("\u004e"));
|
|
|
|
if _eff ==nil {_d .Log .Debug ("N\u006f\u0020\u004e\u0020en\u0074r\u0079\u0020\u002d\u0020\u0073k\u0069\u0070\u0070\u0069\u006e\u0067");continue ;};var _aff *_ga .PdfObjectStream ;switch _afc :=_eff .(type ){case *_ga .PdfObjectDictionary :_ced ,_cdde :=_ga .GetName (_cec .Get ("\u0041\u0053"));
|
|
|
|
if !_cdde {_d .Log .Debug ("\u004e\u006f\u0020\u0041S \u0065\u006e\u0074\u0072\u0079\u0020\u002d\u0020\u0073\u006b\u0069\u0070\u0070\u0069n\u0067");continue ;};_aff ,_cdde =_ga .GetStream (_afc .Get (*_ced ));if !_cdde {_d .Log .Debug ("\u0046o\u0072\u006d\u0020\u006eo\u0074\u0020\u0066\u006f\u0075n\u0064 \u002d \u0073\u006b\u0069\u0070\u0070\u0069\u006eg");
|
|
|
|
continue ;};case *_ga .PdfObjectStream :_aff =_afc ;};if _aff ==nil {_d .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 ;};_fbee ,_afd :=_cf .NewXObjectFormFromStream (_aff );if _afd !=nil {_d .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",_afd );
|
|
|
|
continue ;};_gcc ,_afd :=_fbee .GetContentStream ();if _afd !=nil {_d .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",_afd );continue ;};_bed =append (_bed ,content {_dba :string (_gcc ),_fce :_fbee .Resources });
|
|
|
|
};return _bed ;};func _dcab (_gbb _ga .PdfObject )(_edeb string ,_bdda []_ga .PdfObject ){var _add _e .Buffer ;switch _egce :=_gbb .(type ){case *_ga .PdfIndirectObject :_bdda =append (_bdda ,_egce );_gbb =_egce .PdfObject ;};switch _aaf :=_gbb .(type ){case *_ga .PdfObjectStream :if _dae ,_dcb :=_ga .DecodeStream (_aaf );
|
|
|
|
_dcb ==nil {_add .Write (_dae );_bdda =append (_bdda ,_aaf );};case *_ga .PdfObjectArray :for _ ,_gcef :=range _aaf .Elements (){switch _bbb :=_gcef .(type ){case *_ga .PdfObjectStream :if _gbdd ,_egdc :=_ga .DecodeStream (_bbb );_egdc ==nil {_add .Write (_gbdd );
|
|
|
|
_bdda =append (_bdda ,_bbb );};};};};return _add .String (),_bdda ;};func _afaa (_fab []_ga .PdfObject ,_feee map[_ga .PdfObject ]_ga .PdfObject ){if len (_feee )==0{return ;};for _dfgf ,_ecgc :=range _fab {if _cfc ,_bfdd :=_feee [_ecgc ];_bfdd {_fab [_dfgf ]=_cfc ;
|
|
|
|
continue ;};_feee [_ecgc ]=_ecgc ;switch _dfgc :=_ecgc .(type ){case *_ga .PdfObjectArray :_edd :=make ([]_ga .PdfObject ,_dfgc .Len ());copy (_edd ,_dfgc .Elements ());_afaa (_edd ,_feee );for _dbgf ,_ggcc :=range _edd {_dfgc .Set (_dbgf ,_ggcc );};case *_ga .PdfObjectStreams :_afaa (_dfgc .Elements (),_feee );
|
|
|
|
case *_ga .PdfObjectStream :_geg :=[]_ga .PdfObject {_dfgc .PdfObjectDictionary };_afaa (_geg ,_feee );_dfgc .PdfObjectDictionary =_geg [0].(*_ga .PdfObjectDictionary );case *_ga .PdfObjectDictionary :_geb :=_dfgc .Keys ();_ebeb :=make ([]_ga .PdfObject ,len (_geb ));
|
|
|
|
for _fgfb ,_dace :=range _geb {_ebeb [_fgfb ]=_dfgc .Get (_dace );};_afaa (_ebeb ,_feee );for _ggf ,_ead :=range _geb {_dfgc .Set (_ead ,_ebeb [_ggf ]);};case *_ga .PdfIndirectObject :_cegd :=[]_ga .PdfObject {_dfgc .PdfObject };_afaa (_cegd ,_feee );_dfgc .PdfObject =_cegd [0];
|
|
|
|
};};};
|
|
|
|
|
|
|
|
// Optimize optimizes PDF objects to decrease PDF size.
|
|
|
|
func (_bfa *Image )Optimize (objects []_ga .PdfObject )(_fgf []_ga .PdfObject ,_dff error ){if _bfa .ImageQuality <=0{return objects ,nil ;};_cfae :=_aefd (objects );if len (_cfae )==0{return objects ,nil ;};_abde :=make (map[_ga .PdfObject ]_ga .PdfObject );
|
|
|
|
_gddg :=make (map[_ga .PdfObject ]struct{});for _ ,_bdgc :=range _cfae {_ebed :=_bdgc .Stream .Get ("\u0053\u004d\u0061s\u006b");_gddg [_ebed ]=struct{}{};};for _dec ,_cgb :=range _cfae {_cff :=_cgb .Stream ;if _ ,_bbag :=_gddg [_cff ];_bbag {continue ;
|
|
|
|
};_cef ,_dbg :=_cf .NewXObjectImageFromStream (_cff );if _dbg !=nil {_d .Log .Debug ("\u0045\u0052\u0052\u004f\u0052\u003a\u0020\u0025\u002b\u0076",_dbg );continue ;};switch _cef .Filter .(type ){case *_ga .JBIG2Encoder :continue ;case *_ga .CCITTFaxEncoder :continue ;
|
|
|
|
};_bgd ,_dbg :=_cef .ToImage ();if _dbg !=nil {_d .Log .Debug ("\u0045\u0052\u0052\u004f\u0052\u003a\u0020\u0025\u002b\u0076",_dbg );continue ;};_fac :=_ga .NewDCTEncoder ();_fac .ColorComponents =_bgd .ColorComponents ;_fac .Quality =_bfa .ImageQuality ;
|
|
|
|
_fac .BitsPerComponent =_cgb .BitsPerComponent ;_fac .Width =_cgb .Width ;_fac .Height =_cgb .Height ;_cecc ,_dbg :=_fac .EncodeBytes (_bgd .Data );if _dbg !=nil {_d .Log .Debug ("\u0045\u0052\u0052\u004f\u0052\u003a\u0020\u0025\u002b\u0076",_dbg );continue ;
|
|
|
|
};var _ffdg _ga .StreamEncoder ;_ffdg =_fac ;{_afef :=_ga .NewFlateEncoder ();_cdb :=_ga .NewMultiEncoder ();_cdb .AddEncoder (_afef );_cdb .AddEncoder (_fac );_aeda ,_bgcc :=_cdb .EncodeBytes (_bgd .Data );if _bgcc !=nil {_d .Log .Debug ("\u0045\u0052\u0052\u004f\u0052\u003a\u0020\u0025\u002b\u0076",_bgcc );
|
|
|
|
continue ;};if len (_aeda )< len (_cecc ){_d .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 (_cecc ),len (_aeda ),len (_cff .Stream ));
|
|
|
|
_cecc =_aeda ;_ffdg =_cdb ;};};_bfbd :=len (_cff .Stream );if _bfbd < len (_cecc ){continue ;};_faa :=&_ga .PdfObjectStream {Stream :_cecc };_faa .PdfObjectReference =_cff .PdfObjectReference ;_faa .PdfObjectDictionary =_ga .MakeDict ();_faa .Merge (_cff .PdfObjectDictionary );
|
|
|
|
_faa .Merge (_ffdg .MakeStreamDict ());_faa .Set ("\u004c\u0065\u006e\u0067\u0074\u0068",_ga .MakeInteger (int64 (len (_cecc ))));_abde [_cff ]=_faa ;_cfae [_dec ].Stream =_faa ;};_fgf =make ([]_ga .PdfObject ,len (objects ));copy (_fgf ,objects );_afaa (_fgf ,_abde );
|
|
|
|
return _fgf ,nil ;};
|
2023-03-01 18:45:57 +00:00
|
|
|
|
|
|
|
// CombineDuplicateStreams combines duplicated streams by its data hash.
|
|
|
|
// It implements interface model.Optimizer.
|
|
|
|
type CombineDuplicateStreams struct{};
|
2022-09-10 15:35:04 +00:00
|
|
|
|
2022-09-23 18:05:51 +00:00
|
|
|
// Optimize optimizes PDF objects to decrease PDF size.
|
2023-04-06 19:57:40 +00:00
|
|
|
func (_bebe *ObjectStreams )Optimize (objects []_ga .PdfObject )(_dbc []_ga .PdfObject ,_adga error ){_ffab :=&_ga .PdfObjectStreams {};_afb :=make ([]_ga .PdfObject ,0,len (objects ));for _ ,_bde :=range objects {if _bfbdc ,_caga :=_bde .(*_ga .PdfIndirectObject );
|
|
|
|
_caga &&_bfbdc .GenerationNumber ==0{_ffab .Append (_bde );}else {_afb =append (_afb ,_bde );};};if _ffab .Len ()==0{return _afb ,nil ;};_dbc =make ([]_ga .PdfObject ,0,len (_afb )+_ffab .Len ()+1);if _ffab .Len ()> 1{_dbc =append (_dbc ,_ffab );};_dbc =append (_dbc ,_ffab .Elements ()...);
|
|
|
|
_dbc =append (_dbc ,_afb ...);return _dbc ,nil ;};func _bdeb (_dceg []_ga .PdfObject )objectStructure {_ebec :=objectStructure {};_ggbd :=false ;for _ ,_afca :=range _dceg {switch _ebebe :=_afca .(type ){case *_ga .PdfIndirectObject :_cbdd ,_dgaa :=_ga .GetDict (_ebebe );
|
|
|
|
if !_dgaa {continue ;};_edef ,_dgaa :=_ga .GetName (_cbdd .Get ("\u0054\u0079\u0070\u0065"));if !_dgaa {continue ;};switch _edef .String (){case "\u0043a\u0074\u0061\u006c\u006f\u0067":_ebec ._dcf =_cbdd ;_ggbd =true ;};};if _ggbd {break ;};};if !_ggbd {return _ebec ;
|
|
|
|
};_efda ,_fadc :=_ga .GetDict (_ebec ._dcf .Get ("\u0050\u0061\u0067e\u0073"));if !_fadc {return _ebec ;};_ebec ._dab =_efda ;_agbe ,_fadc :=_ga .GetArray (_efda .Get ("\u004b\u0069\u0064\u0073"));if !_fadc {return _ebec ;};for _ ,_gaed :=range _agbe .Elements (){_ddgb ,_dgcf :=_ga .GetIndirect (_gaed );
|
|
|
|
if !_dgcf {break ;};_ebec ._ebd =append (_ebec ._ebd ,_ddgb );};return _ebec ;};
|
2022-09-10 15:35:04 +00:00
|
|
|
|
2023-04-06 19:57:40 +00:00
|
|
|
// ObjectStreams groups PDF objects to object streams.
|
2023-02-07 17:17:49 +00:00
|
|
|
// It implements interface model.Optimizer.
|
2023-04-06 19:57:40 +00:00
|
|
|
type ObjectStreams struct{};func _fc (_db *_ga .PdfObjectStream )error {_dg ,_af :=_ga .DecodeStream (_db );if _af !=nil {return _af ;};_dga :=_ge .NewContentStreamParser (string (_dg ));_ea ,_af :=_dga .Parse ();if _af !=nil {return _af ;};_ea =_gf (_ea );
|
|
|
|
_gfb :=_ea .Bytes ();if len (_gfb )>=len (_dg ){return nil ;};_ed ,_af :=_ga .MakeStream (_ea .Bytes (),_ga .NewFlateEncoder ());if _af !=nil {return _af ;};_db .Stream =_ed .Stream ;_db .Merge (_ed .PdfObjectDictionary );return nil ;};
|
2022-07-13 21:28:43 +00:00
|
|
|
|
2023-04-06 19:57:40 +00:00
|
|
|
// CombineIdenticalIndirectObjects combines identical indirect objects.
|
|
|
|
// It implements interface model.Optimizer.
|
|
|
|
type CombineIdenticalIndirectObjects struct{};
|
2023-03-01 18:45:57 +00:00
|
|
|
|
2023-04-06 19:57:40 +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 ;
|
|
|
|
};
|
2023-03-01 18:45:57 +00:00
|
|
|
|
|
|
|
// Optimize optimizes PDF objects to decrease PDF size.
|
2023-04-06 19:57:40 +00:00
|
|
|
func (_fad *CombineDuplicateDirectObjects )Optimize (objects []_ga .PdfObject )(_egb []_ga .PdfObject ,_abe error ){_baff (objects );_cdda :=make (map[string ][]*_ga .PdfObjectDictionary );var _acf func (_bg *_ga .PdfObjectDictionary );_acf =func (_aea *_ga .PdfObjectDictionary ){for _ ,_gbc :=range _aea .Keys (){_bfcf :=_aea .Get (_gbc );
|
|
|
|
if _ecde ,_aadd :=_bfcf .(*_ga .PdfObjectDictionary );_aadd {_fdg :=_dd .New ();_fdg .Write ([]byte (_ecde .WriteString ()));_def :=string (_fdg .Sum (nil ));_cdda [_def ]=append (_cdda [_def ],_ecde );_acf (_ecde );};};};for _ ,_bdb :=range objects {_gfdf ,_cac :=_bdb .(*_ga .PdfIndirectObject );
|
|
|
|
if !_cac {continue ;};if _cbfb ,_gff :=_gfdf .PdfObject .(*_ga .PdfObjectDictionary );_gff {_acf (_cbfb );};};_agbd :=make ([]_ga .PdfObject ,0,len (_cdda ));_fdb :=make (map[_ga .PdfObject ]_ga .PdfObject );for _ ,_ddgg :=range _cdda {if len (_ddgg )< 2{continue ;
|
|
|
|
};_ddeae :=_ga .MakeDict ();_ddeae .Merge (_ddgg [0]);_bdga :=_ga .MakeIndirectObject (_ddeae );_agbd =append (_agbd ,_bdga );for _gfdd :=0;_gfdd < len (_ddgg );_gfdd ++{_affc :=_ddgg [_gfdd ];_fdb [_affc ]=_bdga ;};};_egb =make ([]_ga .PdfObject ,len (objects ));
|
|
|
|
copy (_egb ,objects );_egb =append (_agbd ,_egb ...);_afaa (_egb ,_fdb );return _egb ,nil ;};
|
2022-09-23 18:05:51 +00:00
|
|
|
|
2023-04-06 19:57:40 +00:00
|
|
|
// CleanFonts cleans up embedded fonts, reducing font sizes.
|
|
|
|
type CleanFonts struct{
|
2023-01-08 22:34:27 +00:00
|
|
|
|
2023-04-06 19:57:40 +00:00
|
|
|
// Subset embedded fonts if encountered (if true).
|
|
|
|
// Otherwise attempts to reduce the font program.
|
|
|
|
Subset bool ;};type imageModifications struct{Scale float64 ;Encoding _ga .StreamEncoder ;};
|
2022-12-15 21:59:56 +00:00
|
|
|
|
2023-04-06 19:57:40 +00:00
|
|
|
// Optimize optimizes PDF objects to decrease PDF size.
|
|
|
|
func (_gdg *ImagePPI )Optimize (objects []_ga .PdfObject )(_ggb []_ga .PdfObject ,_gecd error ){if _gdg .ImageUpperPPI <=0{return objects ,nil ;};_efee :=_aefd (objects );if len (_efee )==0{return objects ,nil ;};_cbfe :=make (map[_ga .PdfObject ]struct{});
|
|
|
|
for _ ,_gaag :=range _efee {_cffb :=_gaag .Stream .PdfObjectDictionary .Get ("\u0053\u004d\u0061s\u006b");_cbfe [_cffb ]=struct{}{};};_dce :=make (map[*_ga .PdfObjectStream ]*imageInfo );for _ ,_aae :=range _efee {_dce [_aae .Stream ]=_aae ;};var _gbg *_ga .PdfObjectDictionary ;
|
|
|
|
for _ ,_cdgb :=range objects {if _gag ,_dda :=_ga .GetDict (_cdgb );_gbg ==nil &&_dda {if _ebac ,_fcgg :=_ga .GetName (_gag .Get ("\u0054\u0079\u0070\u0065"));_fcgg &&*_ebac =="\u0043a\u0074\u0061\u006c\u006f\u0067"{_gbg =_gag ;};};};if _gbg ==nil {return objects ,nil ;
|
|
|
|
};_ebc ,_gbdf :=_ga .GetDict (_gbg .Get ("\u0050\u0061\u0067e\u0073"));if !_gbdf {return objects ,nil ;};_cfea ,_dgga :=_ga .GetArray (_ebc .Get ("\u004b\u0069\u0064\u0073"));if !_dgga {return objects ,nil ;};for _ ,_bfe :=range _cfea .Elements (){_fdcf :=make (map[string ]*imageInfo );
|
|
|
|
_agg ,_aecb :=_ga .GetDict (_bfe );if !_aecb {continue ;};_ddff ,_ :=_dcab (_agg .Get ("\u0043\u006f\u006e\u0074\u0065\u006e\u0074\u0073"));if len (_ddff )==0{continue ;};_bbg ,_gfab :=_ga .GetDict (_agg .Get ("\u0052e\u0073\u006f\u0075\u0072\u0063\u0065s"));
|
|
|
|
if !_gfab {continue ;};_cbe ,_adgc :=_cf .NewPdfPageResourcesFromDict (_bbg );if _adgc !=nil {_d .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",_adgc );
|
|
|
|
continue ;};_dbd ,_dcg :=_ga .GetDict (_bbg .Get ("\u0058O\u0062\u006a\u0065\u0063\u0074"));if !_dcg {continue ;};_fcga :=_dbd .Keys ();for _ ,_cfd :=range _fcga {if _dfa ,_cdfc :=_ga .GetStream (_dbd .Get (_cfd ));_cdfc {if _cffbf ,_cdfe :=_dce [_dfa ];
|
|
|
|
_cdfe {_fdcf [string (_cfd )]=_cffbf ;};};};_afa :=_ge .NewContentStreamParser (_ddff );_abf ,_adgc :=_afa .Parse ();if _adgc !=nil {_d .Log .Debug ("\u0045\u0052\u0052\u004f\u0052\u003a\u0020\u0025\u002b\u0076",_adgc );continue ;};_dded :=_ge .NewContentStreamProcessor (*_abf );
|
|
|
|
_dded .AddHandler (_ge .HandlerConditionEnumAllOperands ,"",func (_cag *_ge .ContentStreamOperation ,_bbddf _ge .GraphicsState ,_eeac *_cf .PdfPageResources )error {switch _cag .Operand {case "\u0044\u006f":if len (_cag .Params )!=1{_d .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 ;};_ceab ,_dbfe :=_ga .GetName (_cag .Params [0]);if !_dbfe {_d .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 _dgcc ,_efba :=_fdcf [string (*_ceab )];_efba {_abfe :=_bbddf .CTM .ScalingFactorX ();_bag :=_bbddf .CTM .ScalingFactorY ();_bga ,_bfceg :=_abfe /72.0,_bag /72.0;_bgb ,_adf :=float64 (_dgcc .Width )/_bga ,float64 (_dgcc .Height )/_bfceg ;
|
|
|
|
if _bga ==0||_bfceg ==0{_bgb =72.0;_adf =72.0;};_dgcc .PPI =_g .Max (_dgcc .PPI ,_bgb );_dgcc .PPI =_g .Max (_dgcc .PPI ,_adf );};};return nil ;});_adgc =_dded .Process (_cbe );if _adgc !=nil {_d .Log .Debug ("E\u0052\u0052\u004f\u0052 p\u0072o\u0063\u0065\u0073\u0073\u0069n\u0067\u003a\u0020\u0025\u002b\u0076",_adgc );
|
|
|
|
continue ;};};for _ ,_abc :=range _efee {if _ ,_afce :=_cbfe [_abc .Stream ];_afce {continue ;};if _abc .PPI <=_gdg .ImageUpperPPI {continue ;};_abef ,_fcea :=_cf .NewXObjectImageFromStream (_abc .Stream );if _fcea !=nil {_d .Log .Debug ("\u0045\u0052\u0052\u004f\u0052\u003a\u0020\u0025\u002b\u0076",_fcea );
|
|
|
|
continue ;};var _bge imageModifications ;_bge .Scale =_gdg .ImageUpperPPI /_abc .PPI ;if _abc .BitsPerComponent ==1&&_abc .ColorComponents ==1{_dgab :=_g .Round (_abc .PPI /_gdg .ImageUpperPPI );_bfda :=_ddc .NextPowerOf2 (uint (_dgab ));if _ddc .InDelta (float64 (_bfda ),1/_bge .Scale ,0.3){_bge .Scale =float64 (1)/float64 (_bfda );
|
|
|
|
};if _ ,_gge :=_abef .Filter .(*_ga .JBIG2Encoder );!_gge {_bge .Encoding =_ga .NewJBIG2Encoder ();};};if _fcea =_eda (_abef ,_bge );_fcea !=nil {_d .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",_fcea );
|
|
|
|
continue ;};_bge .Encoding =nil ;if _cffa ,_dgae :=_ga .GetStream (_abc .Stream .PdfObjectDictionary .Get ("\u0053\u004d\u0061s\u006b"));_dgae {_cdcc ,_fgcba :=_cf .NewXObjectImageFromStream (_cffa );if _fgcba !=nil {_d .Log .Debug ("\u0045\u0052\u0052\u004f\u0052\u003a\u0020\u0025\u002b\u0076",_fgcba );
|
|
|
|
continue ;};if _fgcba =_eda (_cdcc ,_bge );_fgcba !=nil {_d .Log .Debug ("\u0045\u0052\u0052\u004f\u0052\u003a\u0020\u0025\u002b\u0076",_fgcba );continue ;};};};return objects ,nil ;};
|
2022-10-27 19:04:58 +00:00
|
|
|
|
2023-03-01 18:45:57 +00:00
|
|
|
// Optimize optimizes PDF objects to decrease PDF size.
|
2023-04-06 19:57:40 +00:00
|
|
|
func (_ecc *CombineIdenticalIndirectObjects )Optimize (objects []_ga .PdfObject )(_gdae []_ga .PdfObject ,_eec error ){_baff (objects );_beae :=make (map[_ga .PdfObject ]_ga .PdfObject );_dac :=make (map[_ga .PdfObject ]struct{});_ceea :=make (map[string ][]*_ga .PdfIndirectObject );
|
|
|
|
for _ ,_bgf :=range objects {_gbe ,_gaaf :=_bgf .(*_ga .PdfIndirectObject );if !_gaaf {continue ;};if _cce ,_efe :=_gbe .PdfObject .(*_ga .PdfObjectDictionary );_efe {if _gaac ,_dad :=_cce .Get ("\u0054\u0079\u0070\u0065").(*_ga .PdfObjectName );_dad &&*_gaac =="\u0050\u0061\u0067\u0065"{continue ;
|
|
|
|
};_defe :=_dd .New ();_defe .Write ([]byte (_cce .WriteString ()));_fdfa :=string (_defe .Sum (nil ));_ceea [_fdfa ]=append (_ceea [_fdfa ],_gbe );};};for _ ,_ddef :=range _ceea {if len (_ddef )< 2{continue ;};_gcg :=_ddef [0];for _gccc :=1;_gccc < len (_ddef );
|
|
|
|
_gccc ++{_age :=_ddef [_gccc ];_beae [_age ]=_gcg ;_dac [_age ]=struct{}{};};};_gdae =make ([]_ga .PdfObject ,0,len (objects )-len (_dac ));for _ ,_cad :=range objects {if _ ,_gada :=_dac [_cad ];_gada {continue ;};_gdae =append (_gdae ,_cad );};_afaa (_gdae ,_beae );
|
|
|
|
return _gdae ,nil ;};
|
|
|
|
|
|
|
|
// 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{_dba string ;_fce *_cf .PdfPageResources ;};func _eda (_dfg *_cf .XObjectImage ,_cbd imageModifications )error {_bffa ,_ccf :=_dfg .ToImage ();if _ccf !=nil {return _ccf ;};if _cbd .Scale !=0{_bffa ,_ccf =_cdbd (_bffa ,_cbd .Scale );
|
|
|
|
if _ccf !=nil {return _ccf ;};};if _cbd .Encoding !=nil {_dfg .Filter =_cbd .Encoding ;};_dfg .Decode =nil ;switch _gfdfd :=_dfg .Filter .(type ){case *_ga .FlateEncoder :if _gfdfd .Predictor !=1&&_gfdfd .Predictor !=11{_gfdfd .Predictor =1;};};if _ccf =_dfg .SetImage (_bffa ,nil );
|
|
|
|
_ccf !=nil {_d .Log .Debug ("\u0045\u0072\u0072or\u0020\u0073\u0065\u0074\u0074\u0069\u006e\u0067\u0020\u0069\u006d\u0061\u0067\u0065\u003a\u0020\u0025\u0076",_ccf );return _ccf ;};_dfg .ToPdfObject ();return nil ;};
|
2022-02-05 21:34:53 +00:00
|
|
|
|
2022-12-15 21:59:56 +00:00
|
|
|
// Optimize optimizes PDF objects to decrease PDF size.
|
2023-04-06 19:57:40 +00:00
|
|
|
func (_cbgc *CombineDuplicateStreams )Optimize (objects []_ga .PdfObject )(_bfb []_ga .PdfObject ,_bfcb error ){_cdg :=make (map[_ga .PdfObject ]_ga .PdfObject );_fdc :=make (map[_ga .PdfObject ]struct{});_bcb :=make (map[string ][]*_ga .PdfObjectStream );
|
|
|
|
for _ ,_fcb :=range objects {if _bef ,_efdb :=_fcb .(*_ga .PdfObjectStream );_efdb {_bbe :=_dd .New ();_bbe .Write (_bef .Stream );_bbe .Write ([]byte (_bef .PdfObjectDictionary .WriteString ()));_ggc :=string (_bbe .Sum (nil ));_bcb [_ggc ]=append (_bcb [_ggc ],_bef );
|
|
|
|
};};for _ ,_bdf :=range _bcb {if len (_bdf )< 2{continue ;};_gfde :=_bdf [0];for _efgd :=1;_efgd < len (_bdf );_efgd ++{_fbcb :=_bdf [_efgd ];_cdg [_fbcb ]=_gfde ;_fdc [_fbcb ]=struct{}{};};};_bfb =make ([]_ga .PdfObject ,0,len (objects )-len (_fdc ));
|
|
|
|
for _ ,_dc :=range objects {if _ ,_bbc :=_fdc [_dc ];_bbc {continue ;};_bfb =append (_bfb ,_dc );};_afaa (_bfb ,_cdg );return _bfb ,nil ;};
|
2023-03-01 18:45:57 +00:00
|
|
|
|
|
|
|
// 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 ;};
|
2022-09-23 18:05:51 +00:00
|
|
|
|
2023-04-06 19:57:40 +00:00
|
|
|
// New creates a optimizers chain from options.
|
|
|
|
func New (options Options )*Chain {_egdg :=new (Chain );if options .CleanFonts ||options .SubsetFonts {_egdg .Append (&CleanFonts {Subset :options .SubsetFonts });};if options .CleanContentstream {_egdg .Append (new (CleanContentstream ));};if options .ImageUpperPPI > 0{_gcaa :=new (ImagePPI );
|
|
|
|
_gcaa .ImageUpperPPI =options .ImageUpperPPI ;_egdg .Append (_gcaa );};if options .ImageQuality > 0{_adgd :=new (Image );_adgd .ImageQuality =options .ImageQuality ;_egdg .Append (_adgd );};if options .CombineDuplicateDirectObjects {_egdg .Append (new (CombineDuplicateDirectObjects ));
|
|
|
|
};if options .CombineDuplicateStreams {_egdg .Append (new (CombineDuplicateStreams ));};if options .CombineIdenticalIndirectObjects {_egdg .Append (new (CombineIdenticalIndirectObjects ));};if options .UseObjectStreams {_egdg .Append (new (ObjectStreams ));
|
|
|
|
};if options .CompressStreams {_egdg .Append (new (CompressStreams ));};return _egdg ;};type imageInfo struct{BitsPerComponent int ;ColorComponents int ;Width int ;Height int ;Stream *_ga .PdfObjectStream ;PPI float64 ;};func _baff (_faaa []_ga .PdfObject ){for _dbba ,_eadg :=range _faaa {switch _gcd :=_eadg .(type ){case *_ga .PdfIndirectObject :_gcd .ObjectNumber =int64 (_dbba +1);
|
|
|
|
_gcd .GenerationNumber =0;case *_ga .PdfObjectStream :_gcd .ObjectNumber =int64 (_dbba +1);_gcd .GenerationNumber =0;case *_ga .PdfObjectStreams :_gcd .ObjectNumber =int64 (_dbba +1);_gcd .GenerationNumber =0;};};};func _aefd (_badeb []_ga .PdfObject )[]*imageInfo {_eee :=_ga .PdfObjectName ("\u0053u\u0062\u0074\u0079\u0070\u0065");
|
|
|
|
_ddfe :=make (map[*_ga .PdfObjectStream ]struct{});var _fff []*imageInfo ;for _ ,_fdfd :=range _badeb {_gfa ,_gde :=_ga .GetStream (_fdfd );if !_gde {continue ;};if _ ,_efb :=_ddfe [_gfa ];_efb {continue ;};_ddfe [_gfa ]=struct{}{};_dca :=_gfa .PdfObjectDictionary .Get (_eee );
|
|
|
|
_adbc ,_gde :=_ga .GetName (_dca );if !_gde ||string (*_adbc )!="\u0049\u006d\u0061g\u0065"{continue ;};_fdd :=&imageInfo {Stream :_gfa ,BitsPerComponent :8};if _bdd ,_gdc :=_ga .GetIntVal (_gfa .Get ("\u0042\u0069t\u0073\u0050\u0065r\u0043\u006f\u006d\u0070\u006f\u006e\u0065\u006e\u0074"));
|
|
|
|
_gdc {_fdd .BitsPerComponent =_bdd ;};if _cgf ,_egcd :=_ga .GetIntVal (_gfa .Get ("\u0057\u0069\u0064t\u0068"));_egcd {_fdd .Width =_cgf ;};if _fea ,_gba :=_ga .GetIntVal (_gfa .Get ("\u0048\u0065\u0069\u0067\u0068\u0074"));_gba {_fdd .Height =_fea ;};
|
|
|
|
_feac ,_agd :=_cf .NewPdfColorspaceFromPdfObject (_gfa .Get ("\u0043\u006f\u006c\u006f\u0072\u0053\u0070\u0061\u0063\u0065"));if _agd !=nil {_d .Log .Debug ("\u0045R\u0052\u004f\u0052\u003a\u0020\u0025v",_agd );continue ;};if _feac ==nil {_cdf ,_cddg :=_ga .GetName (_gfa .Get ("\u0046\u0069\u006c\u0074\u0065\u0072"));
|
|
|
|
if _cddg {switch _cdf .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":_feac =_cf .NewPdfColorspaceDeviceGray ();_fdd .BitsPerComponent =1;
|
|
|
|
};};};switch _eag :=_feac .(type ){case *_cf .PdfColorspaceDeviceRGB :_fdd .ColorComponents =3;case *_cf .PdfColorspaceDeviceGray :_fdd .ColorComponents =1;default:_d .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",_eag );
|
|
|
|
continue ;};_fff =append (_fff ,_fdd );};return _fff ;};
|
2022-12-15 21:59:56 +00:00
|
|
|
|
2023-02-07 17:17:49 +00:00
|
|
|
// Optimize optimizes PDF objects to decrease PDF size.
|
2023-04-06 19:57:40 +00:00
|
|
|
func (_a *Chain )Optimize (objects []_ga .PdfObject )(_gc []_ga .PdfObject ,_cgd error ){_gdb :=objects ;for _ ,_ddf :=range _a ._bc {_fd ,_cgg :=_ddf .Optimize (_gdb );if _cgg !=nil {_d .Log .Debug ("\u0045\u0052\u0052OR\u0020\u004f\u0070\u0074\u0069\u006d\u0069\u007a\u0061\u0074\u0069\u006f\u006e\u003a\u0020\u0025\u002b\u0076",_cgg );
|
|
|
|
continue ;};_gdb =_fd ;};return _gdb ,nil ;};func _gf (_dde *_ge .ContentStreamOperations )*_ge .ContentStreamOperations {if _dde ==nil {return nil ;};_gaf :=_ge .ContentStreamOperations {};for _ ,_ba :=range *_dde {switch _ba .Operand {case "\u0042\u0044\u0043","\u0042\u004d\u0043","\u0045\u004d\u0043":continue ;
|
|
|
|
case "\u0054\u006d":if len (_ba .Params )==6{if _cd ,_ddea :=_ga .GetNumbersAsFloat (_ba .Params );_ddea ==nil {if _cd [0]==1&&_cd [1]==0&&_cd [2]==0&&_cd [3]==1{_ba =&_ge .ContentStreamOperation {Params :[]_ga .PdfObject {_ba .Params [4],_ba .Params [5]},Operand :"\u0054\u0064"};
|
|
|
|
};};};};_gaf =append (_gaf ,_ba );};return &_gaf ;};
|
2022-07-13 21:28:43 +00:00
|
|
|
|
2023-04-06 19:57:40 +00:00
|
|
|
// Optimize optimizes PDF objects to decrease PDF size.
|
|
|
|
func (_bba *CompressStreams )Optimize (objects []_ga .PdfObject )(_fdbf []_ga .PdfObject ,_gdaf error ){_fdbf =make ([]_ga .PdfObject ,len (objects ));copy (_fdbf ,objects );for _ ,_affd :=range objects {_fae ,_ffc :=_ga .GetStream (_affd );if !_ffc {continue ;
|
|
|
|
};if _cedc :=_fae .Get ("\u0046\u0069\u006c\u0074\u0065\u0072");_cedc !=nil {if _ ,_bcd :=_ga .GetName (_cedc );_bcd {continue ;};if _aed ,_acc :=_ga .GetArray (_cedc );_acc &&_aed .Len ()> 0{continue ;};};_aec :=_ga .NewFlateEncoder ();var _abb []byte ;
|
|
|
|
_abb ,_gdaf =_aec .EncodeBytes (_fae .Stream );if _gdaf !=nil {return _fdbf ,_gdaf ;};_bbed :=_aec .MakeStreamDict ();if len (_abb )+len (_bbed .WriteString ())< len (_fae .Stream ){_fae .Stream =_abb ;_fae .PdfObjectDictionary .Merge (_bbed );_fae .PdfObjectDictionary .Set ("\u004c\u0065\u006e\u0067\u0074\u0068",_ga .MakeInteger (int64 (len (_fae .Stream ))));
|
|
|
|
};};return _fdbf ,nil ;};func _cdbd (_ggg *_cf .Image ,_dggc float64 )(*_cf .Image ,error ){_edad ,_abg :=_ggg .ToGoImage ();if _abg !=nil {return nil ,_abg ;};var _bfd _ddc .Image ;_fgce ,_cdc :=_edad .(*_ddc .Monochrome );if _cdc {if _abg =_fgce .ResolveDecode ();
|
|
|
|
_abg !=nil {return nil ,_abg ;};_bfd ,_abg =_fgce .Scale (_dggc );if _abg !=nil {return nil ,_abg ;};}else {_eecc :=int (_g .RoundToEven (float64 (_ggg .Width )*_dggc ));_cead :=int (_g .RoundToEven (float64 (_ggg .Height )*_dggc ));_bfd ,_abg =_ddc .NewImage (_eecc ,_cead ,int (_ggg .BitsPerComponent ),_ggg .ColorComponents ,nil ,nil ,nil );
|
|
|
|
if _abg !=nil {return nil ,_abg ;};_ca .CatmullRom .Scale (_bfd ,_bfd .Bounds (),_edad ,_edad .Bounds (),_ca .Over ,&_ca .Options {});};_bce :=_bfd .Base ();_bgdf :=&_cf .Image {Width :int64 (_bce .Width ),Height :int64 (_bce .Height ),BitsPerComponent :int64 (_bce .BitsPerComponent ),ColorComponents :_bce .ColorComponents ,Data :_bce .Data };
|
|
|
|
_bgdf .SetDecode (_bce .Decode );_bgdf .SetAlpha (_bce .Alpha );return _bgdf ,nil ;};func _gfg (_gdd []_ga .PdfObject )(_ccb map[*_ga .PdfObjectStream ]struct{},_eaf error ){_ccb =map[*_ga .PdfObjectStream ]struct{}{};_dea :=map[*_cf .PdfFont ]struct{}{};
|
|
|
|
_bfc :=_bdeb (_gdd );for _ ,_beb :=range _bfc ._ebd {_edg ,_dbb :=_ga .GetDict (_beb .PdfObject );if !_dbb {continue ;};_aab ,_dbb :=_ga .GetDict (_edg .Get ("\u0052e\u0073\u006f\u0075\u0072\u0063\u0065s"));if !_dbb {continue ;};_cee ,_ :=_dcab (_edg .Get ("\u0043\u006f\u006e\u0074\u0065\u006e\u0074\u0073"));
|
|
|
|
_gad ,_gab :=_cf .NewPdfPageResourcesFromDict (_aab );if _gab !=nil {return nil ,_gab ;};_ddfa :=[]content {{_dba :_cee ,_fce :_gad }};_fde :=_deb (_edg .Get ("\u0041\u006e\u006e\u006f\u0074\u0073"));if _fde !=nil {_ddfa =append (_ddfa ,_fde ...);};for _ ,_bbdd :=range _ddfa {_fdf ,_bd :=_cg .NewFromContents (_bbdd ._dba ,_bbdd ._fce );
|
|
|
|
if _bd !=nil {return nil ,_bd ;};_bec ,_ ,_ ,_bd :=_fdf .ExtractPageText ();if _bd !=nil {return nil ,_bd ;};for _ ,_bfce :=range _bec .Marks ().Elements (){if _bfce .Font ==nil {continue ;};if _ ,_cfa :=_dea [_bfce .Font ];!_cfa {_dea [_bfce .Font ]=struct{}{};
|
|
|
|
};};};};_bea :=map[*_ga .PdfObjectStream ][]*_cf .PdfFont {};for _gda :=range _dea {_gca :=_gda .FontDescriptor ();if _gca ==nil ||_gca .FontFile2 ==nil {continue ;};_aef ,_acef :=_ga .GetStream (_gca .FontFile2 );if !_acef {continue ;};_bea [_aef ]=append (_bea [_aef ],_gda );
|
|
|
|
};for _fcd :=range _bea {var _fbe []rune ;var _fga []_gd .GlyphIndex ;for _ ,_gadc :=range _bea [_fcd ]{switch _gec :=_gadc .Encoder ().(type ){case *_b .IdentityEncoder :_aeg :=_gec .RegisteredRunes ();_ad :=make ([]_gd .GlyphIndex ,len (_aeg ));for _ag ,_baf :=range _aeg {_ad [_ag ]=_gd .GlyphIndex (_baf );
|
|
|
|
};_fga =append (_fga ,_ad ...);case *_b .TrueTypeFontEncoder :_gg :=_gec .RegisteredRunes ();_fbe =append (_fbe ,_gg ...);case _b .SimpleEncoder :_egc :=_gec .Charcodes ();for _ ,_ffae :=range _egc {_ddcdf ,_gbf :=_gec .CharcodeToRune (_ffae );if !_gbf {_d .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",_ffae );
|
|
|
|
continue ;};_fbe =append (_fbe ,_ddcdf );};};};_eaf =_fba (_fcd ,_fbe ,_fga );if _eaf !=nil {_d .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",_eaf );
|
|
|
|
return nil ,_eaf ;};_ccb [_fcd ]=struct{}{};};return _ccb ,nil ;};
|
2021-04-23 20:28:14 +00:00
|
|
|
|
2023-03-01 18:45:57 +00:00
|
|
|
// CompressStreams compresses uncompressed streams.
|
|
|
|
// It implements interface model.Optimizer.
|
2023-04-06 19:57:40 +00:00
|
|
|
type CompressStreams struct{};func _fba (_cfg *_ga .PdfObjectStream ,_eba []rune ,_fgc []_gd .GlyphIndex )error {_cfg ,_gdde :=_ga .GetStream (_cfg );if !_gdde {_d .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 _f .New ("\u0066\u006f\u006e\u0074fi\u006c\u0065\u0032\u0020\u006e\u006f\u0074\u0020\u0066\u006f\u0075\u006e\u0064");};_bdg ,_gfdg :=_ga .DecodeStream (_cfg );if _gfdg !=nil {_d .Log .Debug ("\u0044\u0065c\u006f\u0064\u0065 \u0065\u0072\u0072\u006f\u0072\u003a\u0020\u0025\u0076",_gfdg );
|
|
|
|
return _gfdg ;};_cdd ,_gfdg :=_gd .Parse (_e .NewReader (_bdg ));if _gfdg !=nil {_d .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 (_cfg .Stream ));
|
|
|
|
return _gfdg ;};_fef :=_fgc ;if len (_eba )> 0{_fbc :=_cdd .LookupRunes (_eba );_fef =append (_fef ,_fbc ...);};_cdd ,_gfdg =_cdd .SubsetKeepIndices (_fef );if _gfdg !=nil {_d .Log .Debug ("\u0045R\u0052\u004f\u0052\u0020s\u0075\u0062\u0073\u0065\u0074t\u0069n\u0067 \u0066\u006f\u006e\u0074\u003a\u0020\u0025v",_gfdg );
|
|
|
|
return _gfdg ;};var _agb _e .Buffer ;_gfdg =_cdd .Write (&_agb );if _gfdg !=nil {_d .Log .Debug ("\u0045\u0052\u0052\u004fR \u0057\u0072\u0069\u0074\u0069\u006e\u0067\u0020\u0066\u006f\u006e\u0074\u003a\u0020%\u0076",_gfdg );return _gfdg ;};if _agb .Len ()> len (_bdg ){_d .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 ;};_caf ,_gfdg :=_ga .MakeStream (_agb .Bytes (),_ga .NewFlateEncoder ());if _gfdg !=nil {_d .Log .Debug ("\u0045\u0052\u0052\u004fR \u0057\u0072\u0069\u0074\u0069\u006e\u0067\u0020\u0066\u006f\u006e\u0074\u003a\u0020%\u0076",_gfdg );return _gfdg ;
|
|
|
|
};*_cfg =*_caf ;_cfg .Set ("\u004ce\u006e\u0067\u0074\u0068\u0031",_ga .MakeInteger (int64 (_agb .Len ())));return nil ;};
|
2022-06-06 22:48:24 +00:00
|
|
|
|
2023-03-01 18:45:57 +00:00
|
|
|
// CombineDuplicateDirectObjects combines duplicated direct objects by its data hash.
|
|
|
|
// It implements interface model.Optimizer.
|
2023-04-06 19:57:40 +00:00
|
|
|
type CombineDuplicateDirectObjects struct{};type objectStructure struct{_dcf *_ga .PdfObjectDictionary ;_dab *_ga .PdfObjectDictionary ;_ebd []*_ga .PdfIndirectObject ;};
|