unipdf/model/optimize/optimize.go
2022-09-10 15:35:04 +00:00

209 lines
37 KiB
Go

//
// Copyright 2020 FoxyUtils ehf. All rights reserved.
//
// This is a commercial product and requires a license to operate.
// A trial license can be obtained at https://unidoc.io
//
// DO NOT EDIT: generated by unitwist Go source code obfuscator.
//
// Use of this source code is governed by the UniDoc End User License Agreement
// terms that can be accessed at https://unidoc.io/eula/
package optimize ;import (_df "bytes";_d "crypto/md5";_ef "errors";_a "github.com/unidoc/unipdf/v3/common";_ea "github.com/unidoc/unipdf/v3/contentstream";_dbb "github.com/unidoc/unipdf/v3/core";_bc "github.com/unidoc/unipdf/v3/extractor";_e "github.com/unidoc/unipdf/v3/internal/imageutil";
_b "github.com/unidoc/unipdf/v3/internal/textencoding";_db "github.com/unidoc/unipdf/v3/model";_gb "github.com/unidoc/unitype";_ad "golang.org/x/image/draw";_adb "math";);
// CleanContentstream cleans up redundant operands in content streams, including Page and XObject Form
// contents. This process includes:
// 1. Marked content operators are removed.
// 2. Some operands are simplified (shorter form).
// TODO: Add more reduction methods and improving the methods for identifying unnecessary operands.
type CleanContentstream struct{};func _ccba (_fbag []_dbb .PdfObject ){for _caab ,_aggc :=range _fbag {switch _fedf :=_aggc .(type ){case *_dbb .PdfIndirectObject :_fedf .ObjectNumber =int64 (_caab +1);_fedf .GenerationNumber =0;case *_dbb .PdfObjectStream :_fedf .ObjectNumber =int64 (_caab +1);
_fedf .GenerationNumber =0;case *_dbb .PdfObjectStreams :_fedf .ObjectNumber =int64 (_caab +1);_fedf .GenerationNumber =0;};};};
// Optimize optimizes PDF objects to decrease PDF size.
func (_bffc *Image )Optimize (objects []_dbb .PdfObject )(_dbd []_dbb .PdfObject ,_ceb error ){if _bffc .ImageQuality <=0{return objects ,nil ;};_afb :=_acgc (objects );if len (_afb )==0{return objects ,nil ;};_bge :=make (map[_dbb .PdfObject ]_dbb .PdfObject );
_fbfg :=make (map[_dbb .PdfObject ]struct{});for _ ,_afee :=range _afb {_daa :=_afee .Stream .Get ("\u0053\u004d\u0061s\u006b");_fbfg [_daa ]=struct{}{};};for _adbg ,_bdb :=range _afb {_gbgc :=_bdb .Stream ;if _ ,_aafb :=_fbfg [_gbgc ];_aafb {continue ;
};_eeb ,_dad :=_db .NewXObjectImageFromStream (_gbgc );if _dad !=nil {_a .Log .Debug ("\u0045\u0052\u0052\u004f\u0052\u003a\u0020\u0025\u002b\u0076",_dad );continue ;};switch _eeb .Filter .(type ){case *_dbb .JBIG2Encoder :continue ;case *_dbb .CCITTFaxEncoder :continue ;
};_cdbf ,_dad :=_eeb .ToImage ();if _dad !=nil {_a .Log .Debug ("\u0045\u0052\u0052\u004f\u0052\u003a\u0020\u0025\u002b\u0076",_dad );continue ;};_aecg :=_dbb .NewDCTEncoder ();_aecg .ColorComponents =_cdbf .ColorComponents ;_aecg .Quality =_bffc .ImageQuality ;
_aecg .BitsPerComponent =_bdb .BitsPerComponent ;_aecg .Width =_bdb .Width ;_aecg .Height =_bdb .Height ;_cce ,_dad :=_aecg .EncodeBytes (_cdbf .Data );if _dad !=nil {_a .Log .Debug ("\u0045\u0052\u0052\u004f\u0052\u003a\u0020\u0025\u002b\u0076",_dad );
continue ;};var _fgbe _dbb .StreamEncoder ;_fgbe =_aecg ;{_daae :=_dbb .NewFlateEncoder ();_gfe :=_dbb .NewMultiEncoder ();_gfe .AddEncoder (_daae );_gfe .AddEncoder (_aecg );_bfa ,_dgef :=_gfe .EncodeBytes (_cdbf .Data );if _dgef !=nil {_a .Log .Debug ("\u0045\u0052\u0052\u004f\u0052\u003a\u0020\u0025\u002b\u0076",_dgef );
continue ;};if len (_bfa )< len (_cce ){_a .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 (_cce ),len (_bfa ),len (_gbgc .Stream ));
_cce =_bfa ;_fgbe =_gfe ;};};_fgdc :=len (_gbgc .Stream );if _fgdc < len (_cce ){continue ;};_fcab :=&_dbb .PdfObjectStream {Stream :_cce };_fcab .PdfObjectReference =_gbgc .PdfObjectReference ;_fcab .PdfObjectDictionary =_dbb .MakeDict ();_fcab .Merge (_gbgc .PdfObjectDictionary );
_fcab .Merge (_fgbe .MakeStreamDict ());_fcab .Set ("\u004c\u0065\u006e\u0067\u0074\u0068",_dbb .MakeInteger (int64 (len (_cce ))));_bge [_gbgc ]=_fcab ;_afb [_adbg ].Stream =_fcab ;};_dbd =make ([]_dbb .PdfObject ,len (objects ));copy (_dbd ,objects );
_cbbd (_dbd ,_bge );return _dbd ,nil ;};
// Optimize optimizes PDF objects to decrease PDF size.
func (_fbb *CombineDuplicateStreams )Optimize (objects []_dbb .PdfObject )(_afd []_dbb .PdfObject ,_agb error ){_eff :=make (map[_dbb .PdfObject ]_dbb .PdfObject );_bgf :=make (map[_dbb .PdfObject ]struct{});_bgfc :=make (map[string ][]*_dbb .PdfObjectStream );
for _ ,_afe :=range objects {if _fda ,_fce :=_afe .(*_dbb .PdfObjectStream );_fce {_efc :=_d .New ();_efc .Write (_fda .Stream );_efc .Write ([]byte (_fda .PdfObjectDictionary .WriteString ()));_ffe :=string (_efc .Sum (nil ));_bgfc [_ffe ]=append (_bgfc [_ffe ],_fda );
};};for _ ,_feba :=range _bgfc {if len (_feba )< 2{continue ;};_aeb :=_feba [0];for _ffd :=1;_ffd < len (_feba );_ffd ++{_fgf :=_feba [_ffd ];_eff [_fgf ]=_aeb ;_bgf [_fgf ]=struct{}{};};};_afd =make ([]_dbb .PdfObject ,0,len (objects )-len (_bgf ));for _ ,_cgbc :=range objects {if _ ,_gff :=_bgf [_cgbc ];
_gff {continue ;};_afd =append (_afd ,_cgbc );};_cbbd (_afd ,_eff );return _afd ,nil ;};func _aba (_dd []_dbb .PdfObject )(_ddd map[*_dbb .PdfObjectStream ]struct{},_ccg error ){_ddd =map[*_dbb .PdfObjectStream ]struct{}{};_gfg :=map[*_db .PdfFont ]struct{}{};
_cad :=_cbcc (_dd );for _ ,_ggef :=range _cad ._gedd {_edd ,_gab :=_dbb .GetDict (_ggef .PdfObject );if !_gab {continue ;};_fdf ,_gab :=_dbb .GetDict (_edd .Get ("\u0052e\u0073\u006f\u0075\u0072\u0063\u0065s"));if !_gab {continue ;};_cf ,_ :=_dabb (_edd .Get ("\u0043\u006f\u006e\u0074\u0065\u006e\u0074\u0073"));
_bcd ,_ffc :=_db .NewPdfPageResourcesFromDict (_fdf );if _ffc !=nil {return nil ,_ffc ;};_fa :=[]content {{_gca :_cf ,_bgd :_bcd }};_bcf :=_aca (_edd .Get ("\u0041\u006e\u006e\u006f\u0074\u0073"));if _bcf !=nil {_fa =append (_fa ,_bcf ...);};for _ ,_fcd :=range _fa {_abe ,_fdd :=_bc .NewFromContents (_fcd ._gca ,_fcd ._bgd );
if _fdd !=nil {return nil ,_fdd ;};_cd ,_ ,_ ,_fdd :=_abe .ExtractPageText ();if _fdd !=nil {return nil ,_fdd ;};for _ ,_fad :=range _cd .Marks ().Elements (){if _fad .Font ==nil {continue ;};if _ ,_acb :=_gfg [_fad .Font ];!_acb {_gfg [_fad .Font ]=struct{}{};
};};};};_fdda :=map[*_dbb .PdfObjectStream ][]*_db .PdfFont {};for _eac :=range _gfg {_dac :=_eac .FontDescriptor ();if _dac ==nil ||_dac .FontFile2 ==nil {continue ;};_ggeb ,_ba :=_dbb .GetStream (_dac .FontFile2 );if !_ba {continue ;};_fdda [_ggeb ]=append (_fdda [_ggeb ],_eac );
};for _bac :=range _fdda {var _bad []rune ;var _cfa []_gb .GlyphIndex ;for _ ,_bega :=range _fdda [_bac ]{switch _fcc :=_bega .Encoder ().(type ){case *_b .IdentityEncoder :_eeab :=_fcc .RegisteredRunes ();_ccb :=make ([]_gb .GlyphIndex ,len (_eeab ));
for _bcg ,_aaf :=range _eeab {_ccb [_bcg ]=_gb .GlyphIndex (_aaf );};_cfa =append (_cfa ,_ccb ...);case *_b .TrueTypeFontEncoder :_dbf :=_fcc .RegisteredRunes ();_bad =append (_bad ,_dbf ...);case _b .SimpleEncoder :_dacf :=_fcc .Charcodes ();for _ ,_dgba :=range _dacf {_cfd ,_ag :=_fcc .CharcodeToRune (_dgba );
if !_ag {_a .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",_dgba );continue ;};_bad =append (_bad ,_cfd );};};};_ccg =_cec (_bac ,_bad ,_cfa );
if _ccg !=nil {_a .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",_ccg );return nil ,_ccg ;};_ddd [_bac ]=struct{}{};
};return _ddd ,nil ;};func _feg (_fbe *_db .XObjectImage ,_agac imageModifications )error {_gecf ,_bcgg :=_fbe .ToImage ();if _bcgg !=nil {return _bcgg ;};if _agac .Scale !=0{_gecf ,_bcgg =_cadf (_gecf ,_agac .Scale );if _bcgg !=nil {return _bcgg ;};};
if _agac .Encoding !=nil {_fbe .Filter =_agac .Encoding ;};_fbe .Decode =nil ;switch _fge :=_fbe .Filter .(type ){case *_dbb .FlateEncoder :if _fge .Predictor !=1&&_fge .Predictor !=11{_fge .Predictor =1;};};if _bcgg =_fbe .SetImage (_gecf ,nil );_bcgg !=nil {_a .Log .Debug ("\u0045\u0072\u0072or\u0020\u0073\u0065\u0074\u0074\u0069\u006e\u0067\u0020\u0069\u006d\u0061\u0067\u0065\u003a\u0020\u0025\u0076",_bcgg );
return _bcgg ;};_fbe .ToPdfObject ();return nil ;};func _cec (_ebc *_dbb .PdfObjectStream ,_eca []rune ,_fdfb []_gb .GlyphIndex )error {_ebc ,_aafa :=_dbb .GetStream (_ebc );if !_aafa {_a .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 _ef .New ("\u0066\u006f\u006e\u0074fi\u006c\u0065\u0032\u0020\u006e\u006f\u0074\u0020\u0066\u006f\u0075\u006e\u0064");};_ebca ,_cga :=_dbb .DecodeStream (_ebc );if _cga !=nil {_a .Log .Debug ("\u0044\u0065c\u006f\u0064\u0065 \u0065\u0072\u0072\u006f\u0072\u003a\u0020\u0025\u0076",_cga );
return _cga ;};_eee ,_cga :=_gb .Parse (_df .NewReader (_ebca ));if _cga !=nil {_a .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 (_ebc .Stream ));
return _cga ;};_ggd :=_fdfb ;if len (_eca )> 0{_egf :=_eee .LookupRunes (_eca );_ggd =append (_ggd ,_egf ...);};_eee ,_cga =_eee .SubsetKeepIndices (_ggd );if _cga !=nil {_a .Log .Debug ("\u0045R\u0052\u004f\u0052\u0020s\u0075\u0062\u0073\u0065\u0074t\u0069n\u0067 \u0066\u006f\u006e\u0074\u003a\u0020\u0025v",_cga );
return _cga ;};var _eaf _df .Buffer ;_cga =_eee .Write (&_eaf );if _cga !=nil {_a .Log .Debug ("\u0045\u0052\u0052\u004fR \u0057\u0072\u0069\u0074\u0069\u006e\u0067\u0020\u0066\u006f\u006e\u0074\u003a\u0020%\u0076",_cga );return _cga ;};if _eaf .Len ()> len (_ebca ){_a .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 ;};_agg ,_cga :=_dbb .MakeStream (_eaf .Bytes (),_dbb .NewFlateEncoder ());if _cga !=nil {_a .Log .Debug ("\u0045\u0052\u0052\u004fR \u0057\u0072\u0069\u0074\u0069\u006e\u0067\u0020\u0066\u006f\u006e\u0074\u003a\u0020%\u0076",_cga );return _cga ;
};*_ebc =*_agg ;_ebc .Set ("\u004ce\u006e\u0067\u0074\u0068\u0031",_dbb .MakeInteger (int64 (_eaf .Len ())));return nil ;};
// Optimize optimizes PDF objects to decrease PDF size.
func (_bbb *ImagePPI )Optimize (objects []_dbb .PdfObject )(_bcbb []_dbb .PdfObject ,_agbg error ){if _bbb .ImageUpperPPI <=0{return objects ,nil ;};_ebd :=_acgc (objects );if len (_ebd )==0{return objects ,nil ;};_bfb :=make (map[_dbb .PdfObject ]struct{});
for _ ,_eebe :=range _ebd {_dcf :=_eebe .Stream .PdfObjectDictionary .Get ("\u0053\u004d\u0061s\u006b");_bfb [_dcf ]=struct{}{};};_gda :=make (map[*_dbb .PdfObjectStream ]*imageInfo );for _ ,_afa :=range _ebd {_gda [_afa .Stream ]=_afa ;};var _dbed *_dbb .PdfObjectDictionary ;
for _ ,_bea :=range objects {if _gfc ,_gdf :=_dbb .GetDict (_bea );_dbed ==nil &&_gdf {if _efcb ,_dfa :=_dbb .GetName (_gfc .Get ("\u0054\u0079\u0070\u0065"));_dfa &&*_efcb =="\u0043a\u0074\u0061\u006c\u006f\u0067"{_dbed =_gfc ;};};};if _dbed ==nil {return objects ,nil ;
};_aea ,_bdc :=_dbb .GetDict (_dbed .Get ("\u0050\u0061\u0067e\u0073"));if !_bdc {return objects ,nil ;};_aeda ,_cba :=_dbb .GetArray (_aea .Get ("\u004b\u0069\u0064\u0073"));if !_cba {return objects ,nil ;};for _ ,_cbc :=range _aeda .Elements (){_dgbd :=make (map[string ]*imageInfo );
_eadb ,_ggb :=_dbb .GetDict (_cbc );if !_ggb {continue ;};_gaa ,_ :=_dabb (_eadb .Get ("\u0043\u006f\u006e\u0074\u0065\u006e\u0074\u0073"));if len (_gaa )==0{continue ;};_efe ,_cdf :=_dbb .GetDict (_eadb .Get ("\u0052e\u0073\u006f\u0075\u0072\u0063\u0065s"));
if !_cdf {continue ;};_dfe ,_dgae :=_db .NewPdfPageResourcesFromDict (_efe );if _dgae !=nil {_a .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",_dgae );
continue ;};_fegc ,_fege :=_dbb .GetDict (_efe .Get ("\u0058O\u0062\u006a\u0065\u0063\u0074"));if !_fege {continue ;};_dfdg :=_fegc .Keys ();for _ ,_cbf :=range _dfdg {if _gfd ,_cbe :=_dbb .GetStream (_fegc .Get (_cbf ));_cbe {if _fcda ,_gcge :=_gda [_gfd ];
_gcge {_dgbd [string (_cbf )]=_fcda ;};};};_dgcc :=_ea .NewContentStreamParser (_gaa );_fed ,_dgae :=_dgcc .Parse ();if _dgae !=nil {_a .Log .Debug ("\u0045\u0052\u0052\u004f\u0052\u003a\u0020\u0025\u002b\u0076",_dgae );continue ;};_adc :=_ea .NewContentStreamProcessor (*_fed );
_adc .AddHandler (_ea .HandlerConditionEnumAllOperands ,"",func (_deb *_ea .ContentStreamOperation ,_degf _ea .GraphicsState ,_gcgd *_db .PdfPageResources )error {switch _deb .Operand {case "\u0044\u006f":if len (_deb .Params )!=1{_a .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 ;};_fbeg ,_efg :=_dbb .GetName (_deb .Params [0]);if !_efg {_a .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 _befe ,_bcggd :=_dgbd [string (*_fbeg )];_bcggd {_edg :=_degf .CTM .ScalingFactorX ();_fab :=_degf .CTM .ScalingFactorY ();_cbg ,_bgb :=_edg /72.0,_fab /72.0;_beb ,_dbdg :=float64 (_befe .Width )/_cbg ,float64 (_befe .Height )/_bgb ;if _cbg ==0||_bgb ==0{_beb =72.0;
_dbdg =72.0;};_befe .PPI =_adb .Max (_befe .PPI ,_beb );_befe .PPI =_adb .Max (_befe .PPI ,_dbdg );};};return nil ;});_dgae =_adc .Process (_dfe );if _dgae !=nil {_a .Log .Debug ("E\u0052\u0052\u004f\u0052 p\u0072o\u0063\u0065\u0073\u0073\u0069n\u0067\u003a\u0020\u0025\u002b\u0076",_dgae );
continue ;};};for _ ,_fcg :=range _ebd {if _ ,_acc :=_bfb [_fcg .Stream ];_acc {continue ;};if _fcg .PPI <=_bbb .ImageUpperPPI {continue ;};_adea ,_gcgf :=_db .NewXObjectImageFromStream (_fcg .Stream );if _gcgf !=nil {_a .Log .Debug ("\u0045\u0052\u0052\u004f\u0052\u003a\u0020\u0025\u002b\u0076",_gcgf );
continue ;};var _ecac imageModifications ;_ecac .Scale =_bbb .ImageUpperPPI /_fcg .PPI ;if _fcg .BitsPerComponent ==1&&_fcg .ColorComponents ==1{_gcd :=_adb .Round (_fcg .PPI /_bbb .ImageUpperPPI );_aceg :=_e .NextPowerOf2 (uint (_gcd ));if _e .InDelta (float64 (_aceg ),1/_ecac .Scale ,0.3){_ecac .Scale =float64 (1)/float64 (_aceg );
};if _ ,_gad :=_adea .Filter .(*_dbb .JBIG2Encoder );!_gad {_ecac .Encoding =_dbb .NewJBIG2Encoder ();};};if _gcgf =_feg (_adea ,_ecac );_gcgf !=nil {_a .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",_gcgf );
continue ;};_ecac .Encoding =nil ;if _eaaf ,_ccag :=_dbb .GetStream (_fcg .Stream .PdfObjectDictionary .Get ("\u0053\u004d\u0061s\u006b"));_ccag {_dace ,_cbae :=_db .NewXObjectImageFromStream (_eaaf );if _cbae !=nil {_a .Log .Debug ("\u0045\u0052\u0052\u004f\u0052\u003a\u0020\u0025\u002b\u0076",_cbae );
continue ;};if _cbae =_feg (_dace ,_ecac );_cbae !=nil {_a .Log .Debug ("\u0045\u0052\u0052\u004f\u0052\u003a\u0020\u0025\u002b\u0076",_cbae );continue ;};};};return objects ,nil ;};func _bba (_ed *_ea .ContentStreamOperations )*_ea .ContentStreamOperations {if _ed ==nil {return nil ;
};_aa :=_ea .ContentStreamOperations {};for _ ,_cg :=range *_ed {switch _cg .Operand {case "\u0042\u0044\u0043","\u0042\u004d\u0043","\u0045\u004d\u0043":continue ;case "\u0054\u006d":if len (_cg .Params )==6{if _cag ,_fe :=_dbb .GetNumbersAsFloat (_cg .Params );
_fe ==nil {if _cag [0]==1&&_cag [1]==0&&_cag [2]==0&&_cag [3]==1{_cg =&_ea .ContentStreamOperation {Params :[]_dbb .PdfObject {_cg .Params [4],_cg .Params [5]},Operand :"\u0054\u0064"};};};};};_aa =append (_aa ,_cg );};return &_aa ;};
// Optimize optimizes PDF objects to decrease PDF size.
func (_afef *CombineIdenticalIndirectObjects )Optimize (objects []_dbb .PdfObject )(_age []_dbb .PdfObject ,_dcb error ){_ccba (objects );_cbd :=make (map[_dbb .PdfObject ]_dbb .PdfObject );_fbdg :=make (map[_dbb .PdfObject ]struct{});_dfb :=make (map[string ][]*_dbb .PdfIndirectObject );
for _ ,_afea :=range objects {_gcg ,_faa :=_afea .(*_dbb .PdfIndirectObject );if !_faa {continue ;};if _gcf ,_aed :=_gcg .PdfObject .(*_dbb .PdfObjectDictionary );_aed {if _dge ,_cagg :=_gcf .Get ("\u0054\u0079\u0070\u0065").(*_dbb .PdfObjectName );_cagg &&*_dge =="\u0050\u0061\u0067\u0065"{continue ;
};_gcab :=_d .New ();_gcab .Write ([]byte (_gcf .WriteString ()));_eed :=string (_gcab .Sum (nil ));_dfb [_eed ]=append (_dfb [_eed ],_gcg );};};for _ ,_ffcc :=range _dfb {if len (_ffcc )< 2{continue ;};_dgeb :=_ffcc [0];for _dbg :=1;_dbg < len (_ffcc );
_dbg ++{_fdde :=_ffcc [_dbg ];_cbd [_fdde ]=_dgeb ;_fbdg [_fdde ]=struct{}{};};};_age =make ([]_dbb .PdfObject ,0,len (objects )-len (_fbdg ));for _ ,_bdg :=range objects {if _ ,_add :=_fbdg [_bdg ];_add {continue ;};_age =append (_age ,_bdg );};_cbbd (_age ,_cbd );
return _age ,nil ;};type content struct{_gca string ;_bgd *_db .PdfPageResources ;};
// Optimize optimizes PDF objects to decrease PDF size.
func (_daad *ObjectStreams )Optimize (objects []_dbb .PdfObject )(_afff []_dbb .PdfObject ,_gce error ){_cefg :=&_dbb .PdfObjectStreams {};_fgc :=make ([]_dbb .PdfObject ,0,len (objects ));for _ ,_dbca :=range objects {if _fdfc ,_afbe :=_dbca .(*_dbb .PdfIndirectObject );
_afbe &&_fdfc .GenerationNumber ==0{_cefg .Append (_dbca );}else {_fgc =append (_fgc ,_dbca );};};if _cefg .Len ()==0{return _fgc ,nil ;};_afff =make ([]_dbb .PdfObject ,0,len (_fgc )+_cefg .Len ()+1);if _cefg .Len ()> 1{_afff =append (_afff ,_cefg );};
_afff =append (_afff ,_cefg .Elements ()...);_afff =append (_afff ,_fgc ...);return _afff ,nil ;};type imageInfo struct{BitsPerComponent int ;ColorComponents int ;Width int ;Height int ;Stream *_dbb .PdfObjectStream ;PPI float64 ;};func _cbcc (_gcdg []_dbb .PdfObject )objectStructure {_eba :=objectStructure {};
_fbeb :=false ;for _ ,_bca :=range _gcdg {switch _cgf :=_bca .(type ){case *_dbb .PdfIndirectObject :_begg ,_ffb :=_dbb .GetDict (_cgf );if !_ffb {continue ;};_dged ,_ffb :=_dbb .GetName (_begg .Get ("\u0054\u0079\u0070\u0065"));if !_ffb {continue ;};switch _dged .String (){case "\u0043a\u0074\u0061\u006c\u006f\u0067":_eba ._cebf =_begg ;
_fbeb =true ;};};if _fbeb {break ;};};if !_fbeb {return _eba ;};_cddf ,_fcagc :=_dbb .GetDict (_eba ._cebf .Get ("\u0050\u0061\u0067e\u0073"));if !_fcagc {return _eba ;};_eba ._egce =_cddf ;_cgadc ,_fcagc :=_dbb .GetArray (_cddf .Get ("\u004b\u0069\u0064\u0073"));
if !_fcagc {return _eba ;};for _ ,_fag :=range _cgadc .Elements (){_cgbcc ,_cgaf :=_dbb .GetIndirect (_fag );if !_cgaf {break ;};_eba ._gedd =append (_eba ._gedd ,_cgbcc );};return _eba ;};type objectStructure struct{_cebf *_dbb .PdfObjectDictionary ;_egce *_dbb .PdfObjectDictionary ;
_gedd []*_dbb .PdfIndirectObject ;};
// 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 ;};
// New creates a optimizers chain from options.
func New (options Options )*Chain {_ecc :=new (Chain );if options .CleanFonts ||options .SubsetFonts {_ecc .Append (&CleanFonts {Subset :options .SubsetFonts });};if options .CleanContentstream {_ecc .Append (new (CleanContentstream ));};if options .ImageUpperPPI > 0{_ebcc :=new (ImagePPI );
_ebcc .ImageUpperPPI =options .ImageUpperPPI ;_ecc .Append (_ebcc );};if options .ImageQuality > 0{_dcg :=new (Image );_dcg .ImageQuality =options .ImageQuality ;_ecc .Append (_dcg );};if options .CombineDuplicateDirectObjects {_ecc .Append (new (CombineDuplicateDirectObjects ));
};if options .CombineDuplicateStreams {_ecc .Append (new (CombineDuplicateStreams ));};if options .CombineIdenticalIndirectObjects {_ecc .Append (new (CombineIdenticalIndirectObjects ));};if options .UseObjectStreams {_ecc .Append (new (ObjectStreams ));
};if options .CompressStreams {_ecc .Append (new (CompressStreams ));};return _ecc ;};
// CompressStreams compresses uncompressed streams.
// It implements interface model.Optimizer.
type CompressStreams struct{};
// CombineDuplicateDirectObjects combines duplicated direct objects by its data hash.
// It implements interface model.Optimizer.
type CombineDuplicateDirectObjects struct{};
// CombineDuplicateStreams combines duplicated streams by its data hash.
// It implements interface model.Optimizer.
type CombineDuplicateStreams struct{};
// Optimize optimizes PDF objects to decrease PDF size.
func (_bb *Chain )Optimize (objects []_dbb .PdfObject )(_gg []_dbb .PdfObject ,_c error ){_dg :=objects ;for _ ,_ca :=range _bb ._ade {_efb ,_dc :=_ca .Optimize (_dg );if _dc !=nil {_a .Log .Debug ("\u0045\u0052\u0052OR\u0020\u004f\u0070\u0074\u0069\u006d\u0069\u007a\u0061\u0074\u0069\u006f\u006e\u003a\u0020\u0025\u002b\u0076",_dc );
continue ;};_dg =_efb ;};return _dg ,nil ;};
// Optimize optimizes PDF objects to decrease PDF size.
func (_cfg *CleanFonts )Optimize (objects []_dbb .PdfObject )(_ddc []_dbb .PdfObject ,_cdg error ){var _bab map[*_dbb .PdfObjectStream ]struct{};if _cfg .Subset {var _bda error ;_bab ,_bda =_aba (objects );if _bda !=nil {_a .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",_bda );
return nil ,_bda ;};};for _ ,_aab :=range objects {_gbe ,_ggdf :=_dbb .GetStream (_aab );if !_ggdf {continue ;};if _ ,_bff :=_bab [_gbe ];_bff {continue ;};_ced ,_bga :=_dbb .NewEncoderFromStream (_gbe );if _bga !=nil {_a .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",_bga );
continue ;};_bfe ,_bga :=_ced .DecodeStream (_gbe );if _bga !=nil {_a .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",_bga );
continue ;};if len (_bfe )< 4{continue ;};_cgb :=string (_bfe [:4]);if _cgb =="\u004f\u0054\u0054\u004f"{continue ;};if _cgb !="\u0000\u0001\u0000\u0000"&&_cgb !="\u0074\u0072\u0075\u0065"{continue ;};_dag ,_bga :=_gb .Parse (_df .NewReader (_bfe ));if _bga !=nil {_a .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",_bga );
continue ;};_bga =_dag .Optimize ();if _bga !=nil {_a .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",_bga );continue ;};var _fca _df .Buffer ;
_bga =_dag .Write (&_fca );if _bga !=nil {_a .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",_bga );continue ;
};if _fca .Len ()> len (_bfe ){_a .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 ;};_ccc ,_bga :=_dbb .MakeStream (_fca .Bytes (),_dbb .NewFlateEncoder ());if _bga !=nil {continue ;};*_gbe =*_ccc ;_gbe .Set ("\u004ce\u006e\u0067\u0074\u0068\u0031",_dbb .MakeInteger (int64 (_fca .Len ())));};return objects ,nil ;};
// Append appends optimizers to the chain.
func (_f *Chain )Append (optimizers ..._db .Optimizer ){_f ._ade =append (_f ._ade ,optimizers ...)};
// ObjectStreams groups PDF objects to object streams.
// It implements interface model.Optimizer.
type ObjectStreams struct{};type imageModifications struct{Scale float64 ;Encoding _dbb .StreamEncoder ;};func _ac (_ae *_dbb .PdfObjectStream )error {_de ,_beg :=_dbb .DecodeStream (_ae );if _beg !=nil {return _beg ;};_af :=_ea .NewContentStreamParser (string (_de ));
_dgb ,_beg :=_af .Parse ();if _beg !=nil {return _beg ;};_dgb =_bba (_dgb );_dga :=_dgb .Bytes ();if len (_dga )>=len (_de ){return nil ;};_eg ,_beg :=_dbb .MakeStream (_dgb .Bytes (),_dbb .NewFlateEncoder ());if _beg !=nil {return _beg ;};_ae .Stream =_eg .Stream ;
_ae .Merge (_eg .PdfObjectDictionary );return nil ;};
// ImagePPI optimizes images by scaling images such that the PPI (pixels per inch) is never higher than ImageUpperPPI.
// TODO(a5i): Add support for inline images.
// It implements interface model.Optimizer.
type ImagePPI struct{ImageUpperPPI float64 ;};func _cadf (_gcgc *_db .Image ,_cfga float64 )(*_db .Image ,error ){_dab ,_eead :=_gcgc .ToGoImage ();if _eead !=nil {return nil ,_eead ;};var _fgdd _e .Image ;_ged ,_fee :=_dab .(*_e .Monochrome );if _fee {if _eead =_ged .ResolveDecode ();
_eead !=nil {return nil ,_eead ;};_fgdd ,_eead =_ged .Scale (_cfga );if _eead !=nil {return nil ,_eead ;};}else {_agbd :=int (_adb .RoundToEven (float64 (_gcgc .Width )*_cfga ));_edea :=int (_adb .RoundToEven (float64 (_gcgc .Height )*_cfga ));_fgdd ,_eead =_e .NewImage (_agbd ,_edea ,int (_gcgc .BitsPerComponent ),_gcgc .ColorComponents ,nil ,nil ,nil );
if _eead !=nil {return nil ,_eead ;};_ad .CatmullRom .Scale (_fgdd ,_fgdd .Bounds (),_dab ,_dab .Bounds (),_ad .Over ,&_ad .Options {});};_cbb :=_fgdd .Base ();_feea :=&_db .Image {Width :int64 (_cbb .Width ),Height :int64 (_cbb .Height ),BitsPerComponent :int64 (_cbb .BitsPerComponent ),ColorComponents :_cbb .ColorComponents ,Data :_cbb .Data };
_feea .SetDecode (_cbb .Decode );_feea .SetAlpha (_cbb .Alpha );return _feea ,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 ;};
// Optimize optimizes PDF objects to decrease PDF size.
func (_bef *CompressStreams )Optimize (objects []_dbb .PdfObject )(_fef []_dbb .PdfObject ,_acg error ){_fef =make ([]_dbb .PdfObject ,len (objects ));copy (_fef ,objects );for _ ,_fac :=range objects {_ecg ,_gfa :=_dbb .GetStream (_fac );if !_gfa {continue ;
};if _aaca :=_ecg .Get ("\u0046\u0069\u006c\u0074\u0065\u0072");_aaca !=nil {if _ ,_bbc :=_dbb .GetName (_aaca );_bbc {continue ;};if _faec ,_dggc :=_dbb .GetArray (_aaca );_dggc &&_faec .Len ()> 0{continue ;};};_dcbe :=_dbb .NewFlateEncoder ();var _gbf []byte ;
_gbf ,_acg =_dcbe .EncodeBytes (_ecg .Stream );if _acg !=nil {return _fef ,_acg ;};_abc :=_dcbe .MakeStreamDict ();if len (_gbf )+len (_abc .WriteString ())< len (_ecg .Stream ){_ecg .Stream =_gbf ;_ecg .PdfObjectDictionary .Merge (_abc );_ecg .PdfObjectDictionary .Set ("\u004c\u0065\u006e\u0067\u0074\u0068",_dbb .MakeInteger (int64 (len (_ecg .Stream ))));
};};return _fef ,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 _aca (_aeg _dbb .PdfObject )[]content {if _aeg ==nil {return nil ;};_aff ,_bbgd :=_dbb .GetArray (_aeg );if !_bbgd {_a .Log .Debug ("\u0041\u006e\u006e\u006fts\u0020\u006e\u006f\u0074\u0020\u0061\u006e\u0020\u0061\u0072\u0072\u0061\u0079");return nil ;
};var _egc []content ;for _ ,_efba :=range _aff .Elements (){_febe ,_daca :=_dbb .GetDict (_efba );if !_daca {_a .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 ;};_acbe ,_daca :=_dbb .GetDict (_febe .Get ("\u0041\u0050"));if !_daca {_a .Log .Debug ("\u004e\u006f\u0020\u0041P \u0065\u006e\u0074\u0072\u0079\u0020\u002d\u0020\u0073\u006b\u0069\u0070\u0070\u0069n\u0067");continue ;};_abf :=_dbb .TraceToDirectObject (_acbe .Get ("\u004e"));
if _abf ==nil {_a .Log .Debug ("N\u006f\u0020\u004e\u0020en\u0074r\u0079\u0020\u002d\u0020\u0073k\u0069\u0070\u0070\u0069\u006e\u0067");continue ;};var _eaa *_dbb .PdfObjectStream ;switch _fae :=_abf .(type ){case *_dbb .PdfObjectDictionary :_aef ,_ggc :=_dbb .GetName (_febe .Get ("\u0041\u0053"));
if !_ggc {_a .Log .Debug ("\u004e\u006f\u0020\u0041S \u0065\u006e\u0074\u0072\u0079\u0020\u002d\u0020\u0073\u006b\u0069\u0070\u0070\u0069n\u0067");continue ;};_eaa ,_ggc =_dbb .GetStream (_fae .Get (*_aef ));if !_ggc {_a .Log .Debug ("\u0046o\u0072\u006d\u0020\u006eo\u0074\u0020\u0066\u006f\u0075n\u0064 \u002d \u0073\u006b\u0069\u0070\u0070\u0069\u006eg");
continue ;};case *_dbb .PdfObjectStream :_eaa =_fae ;};if _eaa ==nil {_a .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 ;};_gdd ,_gcb :=_db .NewXObjectFormFromStream (_eaa );if _gcb !=nil {_a .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",_gcb );
continue ;};_fba ,_gcb :=_gdd .GetContentStream ();if _gcb !=nil {_a .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",_gcb );continue ;};_egc =append (_egc ,content {_gca :string (_fba ),_bgd :_gdd .Resources });
};return _egc ;};
// Optimize optimizes PDF objects to decrease PDF size.
func (_ge *CleanContentstream )Optimize (objects []_dbb .PdfObject )(_feb []_dbb .PdfObject ,_adf error ){_cc :=map[*_dbb .PdfObjectStream ]struct{}{};var _da []*_dbb .PdfObjectStream ;_gbc :=func (_fb *_dbb .PdfObjectStream ){if _ ,_fea :=_cc [_fb ];!_fea {_cc [_fb ]=struct{}{};
_da =append (_da ,_fb );};};_ggf :=map[_dbb .PdfObject ]bool {};_bcb :=map[_dbb .PdfObject ]bool {};for _ ,_ee :=range objects {switch _caa :=_ee .(type ){case *_dbb .PdfIndirectObject :switch _ga :=_caa .PdfObject .(type ){case *_dbb .PdfObjectDictionary :if _aec ,_deg :=_dbb .GetName (_ga .Get ("\u0054\u0079\u0070\u0065"));
!_deg ||_aec .String ()!="\u0050\u0061\u0067\u0065"{continue ;};if _bd ,_def :=_dbb .GetStream (_ga .Get ("\u0043\u006f\u006e\u0074\u0065\u006e\u0074\u0073"));_def {_gbc (_bd );}else if _dgg ,_dca :=_dbb .GetArray (_ga .Get ("\u0043\u006f\u006e\u0074\u0065\u006e\u0074\u0073"));
_dca {var _eea []*_dbb .PdfObjectStream ;for _ ,_bg :=range _dgg .Elements (){if _aee ,_ec :=_dbb .GetStream (_bg );_ec {_eea =append (_eea ,_aee );};};if len (_eea )> 0{var _bec _df .Buffer ;for _ ,_eab :=range _eea {if _eb ,_fd :=_dbb .DecodeStream (_eab );
_fd ==nil {_bec .Write (_eb );};_ggf [_eab ]=true ;};_cca ,_fbf :=_dbb .MakeStream (_bec .Bytes (),_dbb .NewFlateEncoder ());if _fbf !=nil {return nil ,_fbf ;};_bcb [_cca ]=true ;_ga .Set ("\u0043\u006f\u006e\u0074\u0065\u006e\u0074\u0073",_cca );_gbc (_cca );
};};};case *_dbb .PdfObjectStream :if _ab ,_fbd :=_dbb .GetName (_caa .Get ("\u0054\u0079\u0070\u0065"));!_fbd ||_ab .String ()!="\u0058O\u0062\u006a\u0065\u0063\u0074"{continue ;};if _bcbd ,_fg :=_dbb .GetName (_caa .Get ("\u0053u\u0062\u0074\u0079\u0070\u0065"));
!_fg ||_bcbd .String ()!="\u0046\u006f\u0072\u006d"{continue ;};_gbc (_caa );};};for _ ,_ff :=range _da {_adf =_ac (_ff );if _adf !=nil {return nil ,_adf ;};};_feb =nil ;for _ ,_gf :=range objects {if _ggf [_gf ]{continue ;};_feb =append (_feb ,_gf );};
for _bbg :=range _bcb {_feb =append (_feb ,_bbg );};return _feb ,nil ;};func _dabb (_gbfc _dbb .PdfObject )(_bbe string ,_abd []_dbb .PdfObject ){var _bfc _df .Buffer ;switch _adcf :=_gbfc .(type ){case *_dbb .PdfIndirectObject :_abd =append (_abd ,_adcf );
_gbfc =_adcf .PdfObject ;};switch _dgf :=_gbfc .(type ){case *_dbb .PdfObjectStream :if _edf ,_ccbd :=_dbb .DecodeStream (_dgf );_ccbd ==nil {_bfc .Write (_edf );_abd =append (_abd ,_dgf );};case *_dbb .PdfObjectArray :for _ ,_befa :=range _dgf .Elements (){switch _agec :=_befa .(type ){case *_dbb .PdfObjectStream :if _abff ,_feee :=_dbb .DecodeStream (_agec );
_feee ==nil {_bfc .Write (_abff );_abd =append (_abd ,_agec );};};};};return _bfc .String (),_abd ;};
// CombineIdenticalIndirectObjects combines identical indirect objects.
// It implements interface model.Optimizer.
type CombineIdenticalIndirectObjects struct{};
// Chain allows to use sequence of optimizers.
// It implements interface model.Optimizer.
type Chain struct{_ade []_db .Optimizer };func _acgc (_gde []_dbb .PdfObject )[]*imageInfo {_efd :=_dbb .PdfObjectName ("\u0053u\u0062\u0074\u0079\u0070\u0065");_bcbdb :=make (map[*_dbb .PdfObjectStream ]struct{});var _aedf []*imageInfo ;for _ ,_aaa :=range _gde {_cef ,_fdae :=_dbb .GetStream (_aaa );
if !_fdae {continue ;};if _ ,_cdb :=_bcbdb [_cef ];_cdb {continue ;};_bcbdb [_cef ]=struct{}{};_ffg :=_cef .PdfObjectDictionary .Get (_efd );_fgd ,_fdae :=_dbb .GetName (_ffg );if !_fdae ||string (*_fgd )!="\u0049\u006d\u0061g\u0065"{continue ;};_bbaf :=&imageInfo {Stream :_cef ,BitsPerComponent :8};
if _gbec ,_cdd :=_dbb .GetIntVal (_cef .Get ("\u0042\u0069t\u0073\u0050\u0065r\u0043\u006f\u006d\u0070\u006f\u006e\u0065\u006e\u0074"));_cdd {_bbaf .BitsPerComponent =_gbec ;};if _eafd ,_gac :=_dbb .GetIntVal (_cef .Get ("\u0057\u0069\u0064t\u0068"));_gac {_bbaf .Width =_eafd ;
};if _babf ,_eaca :=_dbb .GetIntVal (_cef .Get ("\u0048\u0065\u0069\u0067\u0068\u0074"));_eaca {_bbaf .Height =_babf ;};_cdda ,_fec :=_db .NewPdfColorspaceFromPdfObject (_cef .Get ("\u0043\u006f\u006c\u006f\u0072\u0053\u0070\u0061\u0063\u0065"));if _fec !=nil {_a .Log .Debug ("\u0045R\u0052\u004f\u0052\u003a\u0020\u0025v",_fec );
continue ;};if _cdda ==nil {_gee ,_gbg :=_dbb .GetName (_cef .Get ("\u0046\u0069\u006c\u0074\u0065\u0072"));if _gbg {switch _gee .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":_cdda =_db .NewPdfColorspaceDeviceGray ();
_bbaf .BitsPerComponent =1;};};};switch _afdg :=_cdda .(type ){case *_db .PdfColorspaceDeviceRGB :_bbaf .ColorComponents =3;case *_db .PdfColorspaceDeviceGray :_bbaf .ColorComponents =1;default:_a .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",_afdg );
continue ;};_aedf =append (_aedf ,_bbaf );};return _aedf ;};
// Optimize optimizes PDF objects to decrease PDF size.
func (_dgc *CombineDuplicateDirectObjects )Optimize (objects []_dbb .PdfObject )(_dbe []_dbb .PdfObject ,_gfb error ){_ccba (objects );_dbeg :=make (map[string ][]*_dbb .PdfObjectDictionary );var _cb func (_dff *_dbb .PdfObjectDictionary );_cb =func (_fcag *_dbb .PdfObjectDictionary ){for _ ,_dcac :=range _fcag .Keys (){_aefg :=_fcag .Get (_dcac );
if _gea ,_dfd :=_aefg .(*_dbb .PdfObjectDictionary );_dfd {_cfe :=_d .New ();_cfe .Write ([]byte (_gea .WriteString ()));_aggb :=string (_cfe .Sum (nil ));_dbeg [_aggb ]=append (_dbeg [_aggb ],_gea );_cb (_gea );};};};for _ ,_fdg :=range objects {_fbc ,_edb :=_fdg .(*_dbb .PdfIndirectObject );
if !_edb {continue ;};if _eeg ,_ggeg :=_fbc .PdfObject .(*_dbb .PdfObjectDictionary );_ggeg {_cb (_eeg );};};_bfg :=make ([]_dbb .PdfObject ,0,len (_dbeg ));_gdg :=make (map[_dbb .PdfObject ]_dbb .PdfObject );for _ ,_agc :=range _dbeg {if len (_agc )< 2{continue ;
};_dde :=_dbb .MakeDict ();_dde .Merge (_agc [0]);_fgb :=_dbb .MakeIndirectObject (_dde );_bfg =append (_bfg ,_fgb );for _adfb :=0;_adfb < len (_agc );_adfb ++{_aafg :=_agc [_adfb ];_gdg [_aafg ]=_fgb ;};};_dbe =make ([]_dbb .PdfObject ,len (objects ));
copy (_dbe ,objects );_dbe =append (_bfg ,_dbe ...);_cbbd (_dbe ,_gdg );return _dbe ,nil ;};func _cbbd (_gafe []_dbb .PdfObject ,_cfdb map[_dbb .PdfObject ]_dbb .PdfObject ){if len (_cfdb )==0{return ;};for _bcef ,_aae :=range _gafe {if _gebe ,_gcga :=_cfdb [_aae ];
_gcga {_gafe [_bcef ]=_gebe ;continue ;};_cfdb [_aae ]=_aae ;switch _ceg :=_aae .(type ){case *_dbb .PdfObjectArray :_cgag :=make ([]_dbb .PdfObject ,_ceg .Len ());copy (_cgag ,_ceg .Elements ());_cbbd (_cgag ,_cfdb );for _gdgg ,_abae :=range _cgag {_ceg .Set (_gdgg ,_abae );
};case *_dbb .PdfObjectStreams :_cbbd (_ceg .Elements (),_cfdb );case *_dbb .PdfObjectStream :_fefd :=[]_dbb .PdfObject {_ceg .PdfObjectDictionary };_cbbd (_fefd ,_cfdb );_ceg .PdfObjectDictionary =_fefd [0].(*_dbb .PdfObjectDictionary );case *_dbb .PdfObjectDictionary :_cfac :=_ceg .Keys ();
_fgcb :=make ([]_dbb .PdfObject ,len (_cfac ));for _bgg ,_addd :=range _cfac {_fgcb [_bgg ]=_ceg .Get (_addd );};_cbbd (_fgcb ,_cfdb );for _ecdc ,_fde :=range _cfac {_ceg .Set (_fde ,_fgcb [_ecdc ]);};case *_dbb .PdfIndirectObject :_cede :=[]_dbb .PdfObject {_ceg .PdfObject };
_cbbd (_cede ,_cfdb );_ceg .PdfObject =_cede [0];};};};