unipdf/model/optimize/optimize.go
2023-03-01 18:45:57 +00:00

210 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 (_cf "bytes";_d "crypto/md5";_dd "errors";_f "github.com/unidoc/unipdf/v3/common";_b "github.com/unidoc/unipdf/v3/contentstream";_af "github.com/unidoc/unipdf/v3/core";_ec "github.com/unidoc/unipdf/v3/extractor";_fb "github.com/unidoc/unipdf/v3/internal/imageutil";
_dg "github.com/unidoc/unipdf/v3/internal/textencoding";_gb "github.com/unidoc/unipdf/v3/model";_g "github.com/unidoc/unitype";_e "golang.org/x/image/draw";_c "math";);
// Optimize optimizes PDF objects to decrease PDF size.
func (_cc *CleanContentstream )Optimize (objects []_af .PdfObject )(_bgf []_af .PdfObject ,_aa error ){_cb :=map[*_af .PdfObjectStream ]struct{}{};var _gad []*_af .PdfObjectStream ;_bc :=func (_bf *_af .PdfObjectStream ){if _ ,_ca :=_cb [_bf ];!_ca {_cb [_bf ]=struct{}{};
_gad =append (_gad ,_bf );};};_ea :=map[_af .PdfObject ]bool {};_dgg :=map[_af .PdfObject ]bool {};for _ ,_ede :=range objects {switch _ab :=_ede .(type ){case *_af .PdfIndirectObject :switch _bbae :=_ab .PdfObject .(type ){case *_af .PdfObjectDictionary :if _edc ,_eae :=_af .GetName (_bbae .Get ("\u0054\u0079\u0070\u0065"));
!_eae ||_edc .String ()!="\u0050\u0061\u0067\u0065"{continue ;};if _cbc ,_ddeg :=_af .GetStream (_bbae .Get ("\u0043\u006f\u006e\u0074\u0065\u006e\u0074\u0073"));_ddeg {_bc (_cbc );}else if _cac ,_eee :=_af .GetArray (_bbae .Get ("\u0043\u006f\u006e\u0074\u0065\u006e\u0074\u0073"));
_eee {var _bd []*_af .PdfObjectStream ;for _ ,_cad :=range _cac .Elements (){if _df ,_ceb :=_af .GetStream (_cad );_ceb {_bd =append (_bd ,_df );};};if len (_bd )> 0{var _ba _cf .Buffer ;for _ ,_ac :=range _bd {if _dff ,_fge :=_af .DecodeStream (_ac );
_fge ==nil {_ba .Write (_dff );};_ea [_ac ]=true ;};_eag ,_edeb :=_af .MakeStream (_ba .Bytes (),_af .NewFlateEncoder ());if _edeb !=nil {return nil ,_edeb ;};_dgg [_eag ]=true ;_bbae .Set ("\u0043\u006f\u006e\u0074\u0065\u006e\u0074\u0073",_eag );_bc (_eag );
};};};case *_af .PdfObjectStream :if _bfb ,_ceg :=_af .GetName (_ab .Get ("\u0054\u0079\u0070\u0065"));!_ceg ||_bfb .String ()!="\u0058O\u0062\u006a\u0065\u0063\u0074"{continue ;};if _age ,_gfb :=_af .GetName (_ab .Get ("\u0053u\u0062\u0074\u0079\u0070\u0065"));
!_gfb ||_age .String ()!="\u0046\u006f\u0072\u006d"{continue ;};_bc (_ab );};};for _ ,_cae :=range _gad {_aa =_fg (_cae );if _aa !=nil {return nil ,_aa ;};};_bgf =nil ;for _ ,_aab :=range objects {if _ea [_aab ]{continue ;};_bgf =append (_bgf ,_aab );};
for _dcg :=range _dgg {_bgf =append (_bgf ,_dcg );};return _bgf ,nil ;};
// Optimize optimizes PDF objects to decrease PDF size.
func (_fgd *CleanFonts )Optimize (objects []_af .PdfObject )(_ecc []_af .PdfObject ,_bfe error ){var _fef map[*_af .PdfObjectStream ]struct{};if _fgd .Subset {var _ggc error ;_fef ,_ggc =_gac (objects );if _ggc !=nil {_f .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",_ggc );
return nil ,_ggc ;};};for _ ,_bcc :=range objects {_add ,_acb :=_af .GetStream (_bcc );if !_acb {continue ;};if _ ,_cd :=_fef [_add ];_cd {continue ;};_cbcf ,_geg :=_af .NewEncoderFromStream (_add );if _geg !=nil {_f .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",_geg );
continue ;};_eeeg ,_geg :=_cbcf .DecodeStream (_add );if _geg !=nil {_f .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",_geg );
continue ;};if len (_eeeg )< 4{continue ;};_ddf :=string (_eeeg [:4]);if _ddf =="\u004f\u0054\u0054\u004f"{continue ;};if _ddf !="\u0000\u0001\u0000\u0000"&&_ddf !="\u0074\u0072\u0075\u0065"{continue ;};_gaa ,_geg :=_g .Parse (_cf .NewReader (_eeeg ));
if _geg !=nil {_f .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",_geg );continue ;};_geg =_gaa .Optimize ();
if _geg !=nil {_f .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",_geg );continue ;};var _ggca _cf .Buffer ;_geg =_gaa .Write (&_ggca );
if _geg !=nil {_f .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",_geg );continue ;};if _ggca .Len ()> len (_eeeg ){_f .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 ;};_caa ,_geg :=_af .MakeStream (_ggca .Bytes (),_af .NewFlateEncoder ());if _geg !=nil {continue ;};*_add =*_caa ;_add .Set ("\u004ce\u006e\u0067\u0074\u0068\u0031",_af .MakeInteger (int64 (_ggca .Len ())));};return objects ,nil ;};func _fg (_ce *_af .PdfObjectStream )error {_ee ,_eb :=_af .DecodeStream (_ce );
if _eb !=nil {return _eb ;};_fdb :=_b .NewContentStreamParser (string (_ee ));_fab ,_eb :=_fdb .Parse ();if _eb !=nil {return _eb ;};_fab =_fd (_fab );_ge :=_fab .Bytes ();if len (_ge )>=len (_ee ){return nil ;};_da ,_eb :=_af .MakeStream (_fab .Bytes (),_af .NewFlateEncoder ());
if _eb !=nil {return _eb ;};_ce .Stream =_da .Stream ;_ce .Merge (_da .PdfObjectDictionary );return nil ;};func _cbg (_dfbd []_af .PdfObject ,_bbgg map[_af .PdfObject ]_af .PdfObject ){if len (_bbgg )==0{return ;};for _feab ,_fbdf :=range _dfbd {if _aec ,_abae :=_bbgg [_fbdf ];
_abae {_dfbd [_feab ]=_aec ;continue ;};_bbgg [_fbdf ]=_fbdf ;switch _aad :=_fbdf .(type ){case *_af .PdfObjectArray :_edfg :=make ([]_af .PdfObject ,_aad .Len ());copy (_edfg ,_aad .Elements ());_cbg (_edfg ,_bbgg );for _fegg ,_gcad :=range _edfg {_aad .Set (_fegg ,_gcad );
};case *_af .PdfObjectStreams :_cbg (_aad .Elements (),_bbgg );case *_af .PdfObjectStream :_cdac :=[]_af .PdfObject {_aad .PdfObjectDictionary };_cbg (_cdac ,_bbgg );_aad .PdfObjectDictionary =_cdac [0].(*_af .PdfObjectDictionary );case *_af .PdfObjectDictionary :_cddd :=_aad .Keys ();
_bcaf :=make ([]_af .PdfObject ,len (_cddd ));for _dbee ,_dgeg :=range _cddd {_bcaf [_dbee ]=_aad .Get (_dgeg );};_cbg (_bcaf ,_bbgg );for _adf ,_fgag :=range _cddd {_aad .Set (_fgag ,_bcaf [_adf ]);};case *_af .PdfIndirectObject :_ggg :=[]_af .PdfObject {_aad .PdfObject };
_cbg (_ggg ,_bbgg );_aad .PdfObject =_ggg [0];};};};func _acgb (_cca []_af .PdfObject ){for _bgc ,_gefa :=range _cca {switch _bdce :=_gefa .(type ){case *_af .PdfIndirectObject :_bdce .ObjectNumber =int64 (_bgc +1);_bdce .GenerationNumber =0;case *_af .PdfObjectStream :_bdce .ObjectNumber =int64 (_bgc +1);
_bdce .GenerationNumber =0;case *_af .PdfObjectStreams :_bdce .ObjectNumber =int64 (_bgc +1);_bdce .GenerationNumber =0;};};};
// 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 ;};
// 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 (_fec *ObjectStreams )Optimize (objects []_af .PdfObject )(_egaf []_af .PdfObject ,_fdda error ){_dbdd :=&_af .PdfObjectStreams {};_abda :=make ([]_af .PdfObject ,0,len (objects ));for _ ,_gfbee :=range objects {if _gdba ,_cfeb :=_gfbee .(*_af .PdfIndirectObject );
_cfeb &&_gdba .GenerationNumber ==0{_dbdd .Append (_gfbee );}else {_abda =append (_abda ,_gfbee );};};if _dbdd .Len ()==0{return _abda ,nil ;};_egaf =make ([]_af .PdfObject ,0,len (_abda )+_dbdd .Len ()+1);if _dbdd .Len ()> 1{_egaf =append (_egaf ,_dbdd );
};_egaf =append (_egaf ,_dbdd .Elements ()...);_egaf =append (_egaf ,_abda ...);return _egaf ,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 imageInfo struct{BitsPerComponent int ;ColorComponents int ;Width int ;Height int ;Stream *_af .PdfObjectStream ;PPI float64 ;};func _gac (_ccf []_af .PdfObject )(_gag map[*_af .PdfObjectStream ]struct{},_gec error ){_gag =map[*_af .PdfObjectStream ]struct{}{};
_ff :=map[*_gb .PdfFont ]struct{}{};_dae :=_ccc (_ccf );for _ ,_gff :=range _dae ._ecbd {_bea ,_bda :=_af .GetDict (_gff .PdfObject );if !_bda {continue ;};_dgf ,_bda :=_af .GetDict (_bea .Get ("\u0052e\u0073\u006f\u0075\u0072\u0063\u0065s"));if !_bda {continue ;
};_ad ,_ :=_ggad (_bea .Get ("\u0043\u006f\u006e\u0074\u0065\u006e\u0074\u0073"));_bfg ,_ebc :=_gb .NewPdfPageResourcesFromDict (_dgf );if _ebc !=nil {return nil ,_ebc ;};_cbf :=[]content {{_eg :_ad ,_de :_bfg }};_dgeb :=_cgd (_bea .Get ("\u0041\u006e\u006e\u006f\u0074\u0073"));
if _dgeb !=nil {_cbf =append (_cbf ,_dgeb ...);};for _ ,_cff :=range _cbf {_cffg ,_ffg :=_ec .NewFromContents (_cff ._eg ,_cff ._de );if _ffg !=nil {return nil ,_ffg ;};_dged ,_ ,_ ,_ffg :=_cffg .ExtractPageText ();if _ffg !=nil {return nil ,_ffg ;};for _ ,_abc :=range _dged .Marks ().Elements (){if _abc .Font ==nil {continue ;
};if _ ,_dfd :=_ff [_abc .Font ];!_dfd {_ff [_abc .Font ]=struct{}{};};};};};_gbe :=map[*_af .PdfObjectStream ][]*_gb .PdfFont {};for _bbda :=range _ff {_dcf :=_bbda .FontDescriptor ();if _dcf ==nil ||_dcf .FontFile2 ==nil {continue ;};_afb ,_bdd :=_af .GetStream (_dcf .FontFile2 );
if !_bdd {continue ;};_gbe [_afb ]=append (_gbe [_afb ],_bbda );};for _eeg :=range _gbe {var _gg []rune ;var _daec []_g .GlyphIndex ;for _ ,_aff :=range _gbe [_eeg ]{switch _cfff :=_aff .Encoder ().(type ){case *_dg .IdentityEncoder :_bca :=_cfff .RegisteredRunes ();
_abd :=make ([]_g .GlyphIndex ,len (_bca ));for _fe ,_cag :=range _bca {_abd [_fe ]=_g .GlyphIndex (_cag );};_daec =append (_daec ,_abd ...);case *_dg .TrueTypeFontEncoder :_bbc :=_cfff .RegisteredRunes ();_gg =append (_gg ,_bbc ...);case _dg .SimpleEncoder :_afd :=_cfff .Charcodes ();
for _ ,_gfg :=range _afd {_dcfd ,_ebce :=_cfff .CharcodeToRune (_gfg );if !_ebce {_f .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",_gfg );
continue ;};_gg =append (_gg ,_dcfd );};};};_gec =_gbff (_eeg ,_gg ,_daec );if _gec !=nil {_f .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",_gec );
return nil ,_gec ;};_gag [_eeg ]=struct{}{};};return _gag ,nil ;};func _cgd (_gda _af .PdfObject )[]content {if _gda ==nil {return nil ;};_bbe ,_agc :=_af .GetArray (_gda );if !_agc {_f .Log .Debug ("\u0041\u006e\u006e\u006fts\u0020\u006e\u006f\u0074\u0020\u0061\u006e\u0020\u0061\u0072\u0072\u0061\u0079");
return nil ;};var _bbef []content ;for _ ,_eec :=range _bbe .Elements (){_dgff ,_eda :=_af .GetDict (_eec );if !_eda {_f .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 ;};_db ,_eda :=_af .GetDict (_dgff .Get ("\u0041\u0050"));if !_eda {_f .Log .Debug ("\u004e\u006f\u0020\u0041P \u0065\u006e\u0074\u0072\u0079\u0020\u002d\u0020\u0073\u006b\u0069\u0070\u0070\u0069n\u0067");continue ;};_cda :=_af .TraceToDirectObject (_db .Get ("\u004e"));
if _cda ==nil {_f .Log .Debug ("N\u006f\u0020\u004e\u0020en\u0074r\u0079\u0020\u002d\u0020\u0073k\u0069\u0070\u0070\u0069\u006e\u0067");continue ;};var _edb *_af .PdfObjectStream ;switch _afdd :=_cda .(type ){case *_af .PdfObjectDictionary :_egd ,_ebd :=_af .GetName (_dgff .Get ("\u0041\u0053"));
if !_ebd {_f .Log .Debug ("\u004e\u006f\u0020\u0041S \u0065\u006e\u0074\u0072\u0079\u0020\u002d\u0020\u0073\u006b\u0069\u0070\u0070\u0069n\u0067");continue ;};_edb ,_ebd =_af .GetStream (_afdd .Get (*_egd ));if !_ebd {_f .Log .Debug ("\u0046o\u0072\u006d\u0020\u006eo\u0074\u0020\u0066\u006f\u0075n\u0064 \u002d \u0073\u006b\u0069\u0070\u0070\u0069\u006eg");
continue ;};case *_af .PdfObjectStream :_edb =_afdd ;};if _edb ==nil {_f .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 ;};_ggd ,_fbg :=_gb .NewXObjectFormFromStream (_edb );if _fbg !=nil {_f .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",_fbg );
continue ;};_fdab ,_fbg :=_ggd .GetContentStream ();if _fbg !=nil {_f .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",_fbg );continue ;};_bbef =append (_bbef ,content {_eg :string (_fdab ),_de :_ggd .Resources });
};return _bbef ;};
// Chain allows to use sequence of optimizers.
// It implements interface model.Optimizer.
type Chain struct{_gbg []_gb .Optimizer };
// Optimize optimizes PDF objects to decrease PDF size.
func (_gbfa *CombineDuplicateDirectObjects )Optimize (objects []_af .PdfObject )(_eff []_af .PdfObject ,_afe error ){_acgb (objects );_acd :=make (map[string ][]*_af .PdfObjectDictionary );var _fdd func (_beg *_af .PdfObjectDictionary );_fdd =func (_eced *_af .PdfObjectDictionary ){for _ ,_ccdg :=range _eced .Keys (){_bdg :=_eced .Get (_ccdg );
if _cfa ,_bceb :=_bdg .(*_af .PdfObjectDictionary );_bceb {_gedb :=_d .New ();_gedb .Write ([]byte (_cfa .WriteString ()));_bfbc :=string (_gedb .Sum (nil ));_acd [_bfbc ]=append (_acd [_bfbc ],_cfa );_fdd (_cfa );};};};for _ ,_ae :=range objects {_cfe ,_ebcb :=_ae .(*_af .PdfIndirectObject );
if !_ebcb {continue ;};if _abfa ,_cef :=_cfe .PdfObject .(*_af .PdfObjectDictionary );_cef {_fdd (_abfa );};};_ebb :=make ([]_af .PdfObject ,0,len (_acd ));_gbfg :=make (map[_af .PdfObject ]_af .PdfObject );for _ ,_eaga :=range _acd {if len (_eaga )< 2{continue ;
};_gea :=_af .MakeDict ();_gea .Merge (_eaga [0]);_faa :=_af .MakeIndirectObject (_gea );_ebb =append (_ebb ,_faa );for _gga :=0;_gga < len (_eaga );_gga ++{_ebbb :=_eaga [_gga ];_gbfg [_ebbb ]=_faa ;};};_eff =make ([]_af .PdfObject ,len (objects ));copy (_eff ,objects );
_eff =append (_ebb ,_eff ...);_cbg (_eff ,_gbfg );return _eff ,nil ;};func _cdf (_ada []_af .PdfObject )[]*imageInfo {_fbga :=_af .PdfObjectName ("\u0053u\u0062\u0074\u0079\u0070\u0065");_acg :=make (map[*_af .PdfObjectStream ]struct{});var _bbac []*imageInfo ;
for _ ,_dbf :=range _ada {_ffgd ,_dba :=_af .GetStream (_dbf );if !_dba {continue ;};if _ ,_gae :=_acg [_ffgd ];_gae {continue ;};_acg [_ffgd ]=struct{}{};_acf :=_ffgd .PdfObjectDictionary .Get (_fbga );_bff ,_dba :=_af .GetName (_acf );if !_dba ||string (*_bff )!="\u0049\u006d\u0061g\u0065"{continue ;
};_acbgc :=&imageInfo {Stream :_ffgd ,BitsPerComponent :8};if _dfa ,_agec :=_af .GetIntVal (_ffgd .Get ("\u0042\u0069t\u0073\u0050\u0065r\u0043\u006f\u006d\u0070\u006f\u006e\u0065\u006e\u0074"));_agec {_acbgc .BitsPerComponent =_dfa ;};if _bdad ,_eef :=_af .GetIntVal (_ffgd .Get ("\u0057\u0069\u0064t\u0068"));
_eef {_acbgc .Width =_bdad ;};if _ebdb ,_gba :=_af .GetIntVal (_ffgd .Get ("\u0048\u0065\u0069\u0067\u0068\u0074"));_gba {_acbgc .Height =_ebdb ;};_ffe ,_bbaee :=_gb .NewPdfColorspaceFromPdfObject (_ffgd .Get ("\u0043\u006f\u006c\u006f\u0072\u0053\u0070\u0061\u0063\u0065"));
if _bbaee !=nil {_f .Log .Debug ("\u0045R\u0052\u004f\u0052\u003a\u0020\u0025v",_bbaee );continue ;};if _ffe ==nil {_gbfgg ,_bbb :=_af .GetName (_ffgd .Get ("\u0046\u0069\u006c\u0074\u0065\u0072"));if _bbb {switch _gbfgg .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":_ffe =_gb .NewPdfColorspaceDeviceGray ();
_acbgc .BitsPerComponent =1;};};};switch _eeca :=_ffe .(type ){case *_gb .PdfColorspaceDeviceRGB :_acbgc .ColorComponents =3;case *_gb .PdfColorspaceDeviceGray :_acbgc .ColorComponents =1;default:_f .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",_eeca );
continue ;};_bbac =append (_bbac ,_acbgc );};return _bbac ;};
// New creates a optimizers chain from options.
func New (options Options )*Chain {_egg :=new (Chain );if options .CleanFonts ||options .SubsetFonts {_egg .Append (&CleanFonts {Subset :options .SubsetFonts });};if options .CleanContentstream {_egg .Append (new (CleanContentstream ));};if options .ImageUpperPPI > 0{_gdcg :=new (ImagePPI );
_gdcg .ImageUpperPPI =options .ImageUpperPPI ;_egg .Append (_gdcg );};if options .ImageQuality > 0{_cgae :=new (Image );_cgae .ImageQuality =options .ImageQuality ;_egg .Append (_cgae );};if options .CombineDuplicateDirectObjects {_egg .Append (new (CombineDuplicateDirectObjects ));
};if options .CombineDuplicateStreams {_egg .Append (new (CombineDuplicateStreams ));};if options .CombineIdenticalIndirectObjects {_egg .Append (new (CombineIdenticalIndirectObjects ));};if options .UseObjectStreams {_egg .Append (new (ObjectStreams ));
};if options .CompressStreams {_egg .Append (new (CompressStreams ));};return _egg ;};
// Optimize optimizes PDF objects to decrease PDF size.
func (_ed *Chain )Optimize (objects []_af .PdfObject )(_dde []_af .PdfObject ,_ga error ){_bb :=objects ;for _ ,_bbg :=range _ed ._gbg {_gf ,_bba :=_bbg .Optimize (_bb );if _bba !=nil {_f .Log .Debug ("\u0045\u0052\u0052OR\u0020\u004f\u0070\u0074\u0069\u006d\u0069\u007a\u0061\u0074\u0069\u006f\u006e\u003a\u0020\u0025\u002b\u0076",_bba );
continue ;};_bb =_gf ;};return _bb ,nil ;};
// Append appends optimizers to the chain.
func (_fa *Chain )Append (optimizers ..._gb .Optimizer ){_fa ._gbg =append (_fa ._gbg ,optimizers ...)};
// 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 ;
};type imageModifications struct{Scale float64 ;Encoding _af .StreamEncoder ;};func _daa (_ccb *_gb .Image ,_aaf float64 )(*_gb .Image ,error ){_def ,_gbb :=_ccb .ToGoImage ();if _gbb !=nil {return nil ,_gbb ;};var _fega _fb .Image ;_befb ,_bcg :=_def .(*_fb .Monochrome );
if _bcg {if _gbb =_befb .ResolveDecode ();_gbb !=nil {return nil ,_gbb ;};_fega ,_gbb =_befb .Scale (_aaf );if _gbb !=nil {return nil ,_gbb ;};}else {_gfbe :=int (_c .RoundToEven (float64 (_ccb .Width )*_aaf ));_fdcb :=int (_c .RoundToEven (float64 (_ccb .Height )*_aaf ));
_fega ,_gbb =_fb .NewImage (_gfbe ,_fdcb ,int (_ccb .BitsPerComponent ),_ccb .ColorComponents ,nil ,nil ,nil );if _gbb !=nil {return nil ,_gbb ;};_e .CatmullRom .Scale (_fega ,_fega .Bounds (),_def ,_def .Bounds (),_e .Over ,&_e .Options {});};_fcd :=_fega .Base ();
_edcd :=&_gb .Image {Width :int64 (_fcd .Width ),Height :int64 (_fcd .Height ),BitsPerComponent :int64 (_fcd .BitsPerComponent ),ColorComponents :_fcd .ColorComponents ,Data :_fcd .Data };_edcd .SetDecode (_fcd .Decode );_edcd .SetAlpha (_fcd .Alpha );
return _edcd ,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 (_eab *CompressStreams )Optimize (objects []_af .PdfObject )(_cde []_af .PdfObject ,_febb error ){_cde =make ([]_af .PdfObject ,len (objects ));copy (_cde ,objects );for _ ,_fcg :=range objects {_fgc ,_fbec :=_af .GetStream (_fcg );if !_fbec {continue ;
};if _bdf :=_fgc .Get ("\u0046\u0069\u006c\u0074\u0065\u0072");_bdf !=nil {if _ ,_aag :=_af .GetName (_bdf );_aag {continue ;};if _dea ,_gedf :=_af .GetArray (_bdf );_gedf &&_dea .Len ()> 0{continue ;};};_gefg :=_af .NewFlateEncoder ();var _afde []byte ;
_afde ,_febb =_gefg .EncodeBytes (_fgc .Stream );if _febb !=nil {return _cde ,_febb ;};_cgf :=_gefg .MakeStreamDict ();if len (_afde )+len (_cgf .WriteString ())< len (_fgc .Stream ){_fgc .Stream =_afde ;_fgc .PdfObjectDictionary .Merge (_cgf );_fgc .PdfObjectDictionary .Set ("\u004c\u0065\u006e\u0067\u0074\u0068",_af .MakeInteger (int64 (len (_fgc .Stream ))));
};};return _cde ,nil ;};
// Optimize optimizes PDF objects to decrease PDF size.
func (_fc *CombineIdenticalIndirectObjects )Optimize (objects []_af .PdfObject )(_dda []_af .PdfObject ,_abe error ){_acgb (objects );_eac :=make (map[_af .PdfObject ]_af .PdfObject );_fabe :=make (map[_af .PdfObject ]struct{});_gdf :=make (map[string ][]*_af .PdfIndirectObject );
for _ ,_cgb :=range objects {_dcfdc ,_feg :=_cgb .(*_af .PdfIndirectObject );if !_feg {continue ;};if _ega ,_acbg :=_dcfdc .PdfObject .(*_af .PdfObjectDictionary );_acbg {if _cbb ,_agcg :=_ega .Get ("\u0054\u0079\u0070\u0065").(*_af .PdfObjectName );_agcg &&*_cbb =="\u0050\u0061\u0067\u0065"{continue ;
};_cga :=_d .New ();_cga .Write ([]byte (_ega .WriteString ()));_effg :=string (_cga .Sum (nil ));_gdf [_effg ]=append (_gdf [_effg ],_dcfdc );};};for _ ,_ggae :=range _gdf {if len (_ggae )< 2{continue ;};_bdb :=_ggae [0];for _gagb :=1;_gagb < len (_ggae );
_gagb ++{_ccg :=_ggae [_gagb ];_eac [_ccg ]=_bdb ;_fabe [_ccg ]=struct{}{};};};_dda =make ([]_af .PdfObject ,0,len (objects )-len (_fabe ));for _ ,_cbe :=range objects {if _ ,_gdc :=_fabe [_cbe ];_gdc {continue ;};_dda =append (_dda ,_cbe );};_cbg (_dda ,_eac );
return _dda ,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 ;};
// Optimize optimizes PDF objects to decrease PDF size.
func (_fbc *Image )Optimize (objects []_af .PdfObject )(_eccf []_af .PdfObject ,_fdc error ){if _fbc .ImageQuality <=0{return objects ,nil ;};_ecad :=_cdf (objects );if len (_ecad )==0{return objects ,nil ;};_fegf :=make (map[_af .PdfObject ]_af .PdfObject );
_fdaf :=make (map[_af .PdfObject ]struct{});for _ ,_egdf :=range _ecad {_aeb :=_egdf .Stream .Get ("\u0053\u004d\u0061s\u006b");_fdaf [_aeb ]=struct{}{};};for _ecdf ,_gcg :=range _ecad {_ebbe :=_gcg .Stream ;if _ ,_baa :=_fdaf [_ebbe ];_baa {continue ;
};_dfe ,_aeff :=_gb .NewXObjectImageFromStream (_ebbe );if _aeff !=nil {_f .Log .Debug ("\u0045\u0052\u0052\u004f\u0052\u003a\u0020\u0025\u002b\u0076",_aeff );continue ;};switch _dfe .Filter .(type ){case *_af .JBIG2Encoder :continue ;case *_af .CCITTFaxEncoder :continue ;
};_eabf ,_aeff :=_dfe .ToImage ();if _aeff !=nil {_f .Log .Debug ("\u0045\u0052\u0052\u004f\u0052\u003a\u0020\u0025\u002b\u0076",_aeff );continue ;};_ecf :=_af .NewDCTEncoder ();_ecf .ColorComponents =_eabf .ColorComponents ;_ecf .Quality =_fbc .ImageQuality ;
_ecf .BitsPerComponent =_gcg .BitsPerComponent ;_ecf .Width =_gcg .Width ;_ecf .Height =_gcg .Height ;_babc ,_aeff :=_ecf .EncodeBytes (_eabf .Data );if _aeff !=nil {_f .Log .Debug ("\u0045\u0052\u0052\u004f\u0052\u003a\u0020\u0025\u002b\u0076",_aeff );
continue ;};var _gcb _af .StreamEncoder ;_gcb =_ecf ;{_cdb :=_af .NewFlateEncoder ();_eea :=_af .NewMultiEncoder ();_eea .AddEncoder (_cdb );_eea .AddEncoder (_ecf );_cbee ,_bfce :=_eea .EncodeBytes (_eabf .Data );if _bfce !=nil {_f .Log .Debug ("\u0045\u0052\u0052\u004f\u0052\u003a\u0020\u0025\u002b\u0076",_bfce );
continue ;};if len (_cbee )< len (_babc ){_f .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 (_babc ),len (_cbee ),len (_ebbe .Stream ));
_babc =_cbee ;_gcb =_eea ;};};_faeg :=len (_ebbe .Stream );if _faeg < len (_babc ){continue ;};_abba :=&_af .PdfObjectStream {Stream :_babc };_abba .PdfObjectReference =_ebbe .PdfObjectReference ;_abba .PdfObjectDictionary =_af .MakeDict ();_abba .Merge (_ebbe .PdfObjectDictionary );
_abba .Merge (_gcb .MakeStreamDict ());_abba .Set ("\u004c\u0065\u006e\u0067\u0074\u0068",_af .MakeInteger (int64 (len (_babc ))));_fegf [_ebbe ]=_abba ;_ecad [_ecdf ].Stream =_abba ;};_eccf =make ([]_af .PdfObject ,len (objects ));copy (_eccf ,objects );
_cbg (_eccf ,_fegf );return _eccf ,nil ;};func _ggad (_cdbg _af .PdfObject )(_bee string ,_abea []_af .PdfObject ){var _ceec _cf .Buffer ;switch _gedfd :=_cdbg .(type ){case *_af .PdfIndirectObject :_abea =append (_abea ,_gedfd );_cdbg =_gedfd .PdfObject ;
};switch _ege :=_cdbg .(type ){case *_af .PdfObjectStream :if _cfaa ,_dgegc :=_af .DecodeStream (_ege );_dgegc ==nil {_ceec .Write (_cfaa );_abea =append (_abea ,_ege );};case *_af .PdfObjectArray :for _ ,_bbcd :=range _ege .Elements (){switch _ccbf :=_bbcd .(type ){case *_af .PdfObjectStream :if _gbc ,_gge :=_af .DecodeStream (_ccbf );
_gge ==nil {_ceec .Write (_gbc );_abea =append (_abea ,_ccbf );};};};};return _ceec .String (),_abea ;};func _gbff (_ece *_af .PdfObjectStream ,_gde []rune ,_ddg []_g .GlyphIndex )error {_ece ,_ged :=_af .GetStream (_ece );if !_ged {_f .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 _dd .New ("\u0066\u006f\u006e\u0074fi\u006c\u0065\u0032\u0020\u006e\u006f\u0074\u0020\u0066\u006f\u0075\u006e\u0064");};_gef ,_gee :=_af .DecodeStream (_ece );if _gee !=nil {_f .Log .Debug ("\u0044\u0065c\u006f\u0064\u0065 \u0065\u0072\u0072\u006f\u0072\u003a\u0020\u0025\u0076",_gee );
return _gee ;};_aca ,_gee :=_g .Parse (_cf .NewReader (_gef ));if _gee !=nil {_f .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 (_ece .Stream ));
return _gee ;};_cg :=_ddg ;if len (_gde )> 0{_afa :=_aca .LookupRunes (_gde );_cg =append (_cg ,_afa ...);};_aca ,_gee =_aca .SubsetKeepIndices (_cg );if _gee !=nil {_f .Log .Debug ("\u0045R\u0052\u004f\u0052\u0020s\u0075\u0062\u0073\u0065\u0074t\u0069n\u0067 \u0066\u006f\u006e\u0074\u003a\u0020\u0025v",_gee );
return _gee ;};var _bdc _cf .Buffer ;_gee =_aca .Write (&_bdc );if _gee !=nil {_f .Log .Debug ("\u0045\u0052\u0052\u004fR \u0057\u0072\u0069\u0074\u0069\u006e\u0067\u0020\u0066\u006f\u006e\u0074\u003a\u0020%\u0076",_gee );return _gee ;};if _bdc .Len ()> len (_gef ){_f .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 ;};_cbd ,_gee :=_af .MakeStream (_bdc .Bytes (),_af .NewFlateEncoder ());if _gee !=nil {_f .Log .Debug ("\u0045\u0052\u0052\u004fR \u0057\u0072\u0069\u0074\u0069\u006e\u0067\u0020\u0066\u006f\u006e\u0074\u003a\u0020%\u0076",_gee );return _gee ;
};*_ece =*_cbd ;_ece .Set ("\u004ce\u006e\u0067\u0074\u0068\u0031",_af .MakeInteger (int64 (_bdc .Len ())));return nil ;};
// Optimize optimizes PDF objects to decrease PDF size.
func (_ded *ImagePPI )Optimize (objects []_af .PdfObject )(_gcd []_af .PdfObject ,_fee error ){if _ded .ImageUpperPPI <=0{return objects ,nil ;};_bed :=_cdf (objects );if len (_bed )==0{return objects ,nil ;};_bcfc :=make (map[_af .PdfObject ]struct{});
for _ ,_dcb :=range _bed {_fgb :=_dcb .Stream .PdfObjectDictionary .Get ("\u0053\u004d\u0061s\u006b");_bcfc [_fgb ]=struct{}{};};_gaac :=make (map[*_af .PdfObjectStream ]*imageInfo );for _ ,_agd :=range _bed {_gaac [_agd .Stream ]=_agd ;};var _aea *_af .PdfObjectDictionary ;
for _ ,_afddd :=range objects {if _dfb ,_cbfe :=_af .GetDict (_afddd );_aea ==nil &&_cbfe {if _abff ,_dac :=_af .GetName (_dfb .Get ("\u0054\u0079\u0070\u0065"));_dac &&*_abff =="\u0043a\u0074\u0061\u006c\u006f\u0067"{_aea =_dfb ;};};};if _aea ==nil {return objects ,nil ;
};_efc ,_bae :=_af .GetDict (_aea .Get ("\u0050\u0061\u0067e\u0073"));if !_bae {return objects ,nil ;};_begc ,_fcc :=_af .GetArray (_efc .Get ("\u004b\u0069\u0064\u0073"));if !_fcc {return objects ,nil ;};for _ ,_cee :=range _begc .Elements (){_gdfg :=make (map[string ]*imageInfo );
_febg ,_gbaf :=_af .GetDict (_cee );if !_gbaf {continue ;};_dedf ,_ :=_ggad (_febg .Get ("\u0043\u006f\u006e\u0074\u0065\u006e\u0074\u0073"));if len (_dedf )==0{continue ;};_dfag ,_gada :=_af .GetDict (_febg .Get ("\u0052e\u0073\u006f\u0075\u0072\u0063\u0065s"));
if !_gada {continue ;};_ggdc ,_fbed :=_gb .NewPdfPageResourcesFromDict (_dfag );if _fbed !=nil {_f .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",_fbed );
continue ;};_cgc ,_eeaf :=_af .GetDict (_dfag .Get ("\u0058O\u0062\u006a\u0065\u0063\u0074"));if !_eeaf {continue ;};_ebe :=_cgc .Keys ();for _ ,_fba :=range _ebe {if _dcbb ,_ddd :=_af .GetStream (_cgc .Get (_fba ));_ddd {if _ffgb ,_gfc :=_gaac [_dcbb ];
_gfc {_gdfg [string (_fba )]=_ffgb ;};};};_aba :=_b .NewContentStreamParser (_dedf );_cage ,_fbed :=_aba .Parse ();if _fbed !=nil {_f .Log .Debug ("\u0045\u0052\u0052\u004f\u0052\u003a\u0020\u0025\u002b\u0076",_fbed );continue ;};_bbde :=_b .NewContentStreamProcessor (*_cage );
_bbde .AddHandler (_b .HandlerConditionEnumAllOperands ,"",func (_gabe *_b .ContentStreamOperation ,_cacf _b .GraphicsState ,_ecb *_gb .PdfPageResources )error {switch _gabe .Operand {case "\u0044\u006f":if len (_gabe .Params )!=1{_f .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 ;};_cdgd ,_cdc :=_af .GetName (_gabe .Params [0]);if !_cdc {_f .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 _fac ,_fdaa :=_gdfg [string (*_cdgd )];_fdaa {_fgf :=_cacf .CTM .ScalingFactorX ();_eeafe :=_cacf .CTM .ScalingFactorY ();_gaea ,_aed :=_fgf /72.0,_eeafe /72.0;_gacd ,_fegc :=float64 (_fac .Width )/_gaea ,float64 (_fac .Height )/_aed ;
if _gaea ==0||_aed ==0{_gacd =72.0;_fegc =72.0;};_fac .PPI =_c .Max (_fac .PPI ,_gacd );_fac .PPI =_c .Max (_fac .PPI ,_fegc );};};return nil ;});_fbed =_bbde .Process (_ggdc );if _fbed !=nil {_f .Log .Debug ("E\u0052\u0052\u004f\u0052 p\u0072o\u0063\u0065\u0073\u0073\u0069n\u0067\u003a\u0020\u0025\u002b\u0076",_fbed );
continue ;};};for _ ,_agg :=range _bed {if _ ,_abab :=_bcfc [_agg .Stream ];_abab {continue ;};if _agg .PPI <=_ded .ImageUpperPPI {continue ;};_gca ,_cffe :=_gb .NewXObjectImageFromStream (_agg .Stream );if _cffe !=nil {_f .Log .Debug ("\u0045\u0052\u0052\u004f\u0052\u003a\u0020\u0025\u002b\u0076",_cffe );
continue ;};var _ceed imageModifications ;_ceed .Scale =_ded .ImageUpperPPI /_agg .PPI ;if _agg .BitsPerComponent ==1&&_agg .ColorComponents ==1{_cgcg :=_c .Round (_agg .PPI /_ded .ImageUpperPPI );_gace :=_fb .NextPowerOf2 (uint (_cgcg ));if _fb .InDelta (float64 (_gace ),1/_ceed .Scale ,0.3){_ceed .Scale =float64 (1)/float64 (_gace );
};if _ ,_eaa :=_gca .Filter .(*_af .JBIG2Encoder );!_eaa {_ceed .Encoding =_af .NewJBIG2Encoder ();};};if _cffe =_affg (_gca ,_ceed );_cffe !=nil {_f .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",_cffe );
continue ;};_ceed .Encoding =nil ;if _beab ,_ageg :=_af .GetStream (_agg .Stream .PdfObjectDictionary .Get ("\u0053\u004d\u0061s\u006b"));_ageg {_bffc ,_edba :=_gb .NewXObjectImageFromStream (_beab );if _edba !=nil {_f .Log .Debug ("\u0045\u0052\u0052\u004f\u0052\u003a\u0020\u0025\u002b\u0076",_edba );
continue ;};if _edba =_affg (_bffc ,_ceed );_edba !=nil {_f .Log .Debug ("\u0045\u0052\u0052\u004f\u0052\u003a\u0020\u0025\u002b\u0076",_edba );continue ;};};};return objects ,nil ;};type content struct{_eg string ;_de *_gb .PdfPageResources ;};
// ObjectStreams groups PDF objects to object streams.
// It implements interface model.Optimizer.
type ObjectStreams struct{};
// CombineIdenticalIndirectObjects combines identical indirect objects.
// It implements interface model.Optimizer.
type CombineIdenticalIndirectObjects struct{};func _fd (_dc *_b .ContentStreamOperations )*_b .ContentStreamOperations {if _dc ==nil {return nil ;};_ag :=_b .ContentStreamOperations {};for _ ,_be :=range *_dc {switch _be .Operand {case "\u0042\u0044\u0043","\u0042\u004d\u0043","\u0045\u004d\u0043":continue ;
case "\u0054\u006d":if len (_be .Params )==6{if _ef ,_dgc :=_af .GetNumbersAsFloat (_be .Params );_dgc ==nil {if _ef [0]==1&&_ef [1]==0&&_ef [2]==0&&_ef [3]==1{_be =&_b .ContentStreamOperation {Params :[]_af .PdfObject {_be .Params [4],_be .Params [5]},Operand :"\u0054\u0064"};
};};};};_ag =append (_ag ,_be );};return &_ag ;};type objectStructure struct{_eed *_af .PdfObjectDictionary ;_cgeb *_af .PdfObjectDictionary ;_ecbd []*_af .PdfIndirectObject ;};func _affg (_ffb *_gb .XObjectImage ,_cegc imageModifications )error {_gbd ,_cdgb :=_ffb .ToImage ();
if _cdgb !=nil {return _cdgb ;};if _cegc .Scale !=0{_gbd ,_cdgb =_daa (_gbd ,_cegc .Scale );if _cdgb !=nil {return _cdgb ;};};if _cegc .Encoding !=nil {_ffb .Filter =_cegc .Encoding ;};_ffb .Decode =nil ;switch _gdbg :=_ffb .Filter .(type ){case *_af .FlateEncoder :if _gdbg .Predictor !=1&&_gdbg .Predictor !=11{_gdbg .Predictor =1;
};};if _cdgb =_ffb .SetImage (_gbd ,nil );_cdgb !=nil {_f .Log .Debug ("\u0045\u0072\u0072or\u0020\u0073\u0065\u0074\u0074\u0069\u006e\u0067\u0020\u0069\u006d\u0061\u0067\u0065\u003a\u0020\u0025\u0076",_cdgb );return _cdgb ;};_ffb .ToPdfObject ();return nil ;
};
// CompressStreams compresses uncompressed streams.
// It implements interface model.Optimizer.
type CompressStreams struct{};func _ccc (_aedf []_af .PdfObject )objectStructure {_aga :=objectStructure {};_ddge :=false ;for _ ,_cgfd :=range _aedf {switch _dbc :=_cgfd .(type ){case *_af .PdfIndirectObject :_fad ,_afff :=_af .GetDict (_dbc );if !_afff {continue ;
};_fabc ,_afff :=_af .GetName (_fad .Get ("\u0054\u0079\u0070\u0065"));if !_afff {continue ;};switch _fabc .String (){case "\u0043a\u0074\u0061\u006c\u006f\u0067":_aga ._eed =_fad ;_ddge =true ;};};if _ddge {break ;};};if !_ddge {return _aga ;};_fgca ,_affe :=_af .GetDict (_aga ._eed .Get ("\u0050\u0061\u0067e\u0073"));
if !_affe {return _aga ;};_aga ._cgeb =_fgca ;_cgac ,_affe :=_af .GetArray (_fgca .Get ("\u004b\u0069\u0064\u0073"));if !_affe {return _aga ;};for _ ,_gaceg :=range _cgac .Elements (){_fcdg ,_dbde :=_af .GetIndirect (_gaceg );if !_dbde {break ;};_aga ._ecbd =append (_aga ._ecbd ,_fcdg );
};return _aga ;};
// CombineDuplicateDirectObjects combines duplicated direct objects by its data hash.
// It implements interface model.Optimizer.
type CombineDuplicateDirectObjects struct{};
// Optimize optimizes PDF objects to decrease PDF size.
func (_gedbd *CombineDuplicateStreams )Optimize (objects []_af .PdfObject )(_fga []_af .PdfObject ,_beaa error ){_feb :=make (map[_af .PdfObject ]_af .PdfObject );_gbeg :=make (map[_af .PdfObject ]struct{});_cdad :=make (map[string ][]*_af .PdfObjectStream );
for _ ,_bge :=range objects {if _ccfc ,_ddc :=_bge .(*_af .PdfObjectStream );_ddc {_bab :=_d .New ();_bab .Write (_ccfc .Stream );_bab .Write ([]byte (_ccfc .PdfObjectDictionary .WriteString ()));_bfc :=string (_bab .Sum (nil ));_cdad [_bfc ]=append (_cdad [_bfc ],_ccfc );
};};for _ ,_gfgg :=range _cdad {if len (_gfgg )< 2{continue ;};_gc :=_gfgg [0];for _gfe :=1;_gfe < len (_gfgg );_gfe ++{_bbdag :=_gfgg [_gfe ];_feb [_bbdag ]=_gc ;_gbeg [_bbdag ]=struct{}{};};};_fga =make ([]_af .PdfObject ,0,len (objects )-len (_gbeg ));
for _ ,_dag :=range objects {if _ ,_dbd :=_gbeg [_dag ];_dbd {continue ;};_fga =append (_fga ,_dag );};_cbg (_fga ,_feb );return _fga ,nil ;};