github.com/unidoc/unipdf/v3@v3.55.0/model/optimize/optimize.go (about)

     1  //
     2  // Copyright 2020 FoxyUtils ehf. All rights reserved.
     3  //
     4  // This is a commercial product and requires a license to operate.
     5  // A trial license can be obtained at https://unidoc.io
     6  //
     7  // DO NOT EDIT: generated by unitwist Go source code obfuscator.
     8  //
     9  // Use of this source code is governed by the UniDoc End User License Agreement
    10  // terms that can be accessed at https://unidoc.io/eula/
    11  
    12  package optimize ;import (_df "bytes";_ce "crypto/md5";_e "errors";_ac "fmt";_f "github.com/unidoc/unipdf/v3/common";_bf "github.com/unidoc/unipdf/v3/contentstream";_ba "github.com/unidoc/unipdf/v3/core";_d "github.com/unidoc/unipdf/v3/extractor";_fg "github.com/unidoc/unipdf/v3/internal/imageutil";
    13  _cf "github.com/unidoc/unipdf/v3/internal/textencoding";_cff "github.com/unidoc/unipdf/v3/model";_gc "github.com/unidoc/unitype";_c "golang.org/x/image/draw";_b "math";_a "strings";);
    14  
    15  // Optimize optimizes PDF objects to decrease PDF size.
    16  func (_efeb *CleanFonts )Optimize (objects []_ba .PdfObject )(_ee []_ba .PdfObject ,_cbbf error ){var _gec map[*_ba .PdfObjectStream ]struct{};if _efeb .Subset {var _gfga error ;_gec ,_gfga =_egf (objects );if _gfga !=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",_gfga );
    17  return nil ,_gfga ;};};for _ ,_fa :=range objects {_cgg ,_gbg :=_ba .GetStream (_fa );if !_gbg {continue ;};if _ ,_gcgd :=_gec [_cgg ];_gcgd {continue ;};_bde ,_eee :=_ba .NewEncoderFromStream (_cgg );if _eee !=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",_eee );
    18  continue ;};_dae ,_eee :=_bde .DecodeStream (_cgg );if _eee !=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",_eee );
    19  continue ;};if len (_dae )< 4{continue ;};_cea :=string (_dae [:4]);if _cea =="\u004f\u0054\u0054\u004f"{continue ;};if _cea !="\u0000\u0001\u0000\u0000"&&_cea !="\u0074\u0072\u0075\u0065"{continue ;};_dac ,_eee :=_gc .Parse (_df .NewReader (_dae ));if _eee !=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",_eee );
    20  continue ;};_eee =_dac .Optimize ();if _eee !=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",_eee );continue ;};var _ae _df .Buffer ;
    21  _eee =_dac .Write (&_ae );if _eee !=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",_eee );continue ;
    22  };if _ae .Len ()> len (_dae ){_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");
    23  continue ;};_dca ,_eee :=_ba .MakeStream (_ae .Bytes (),_ba .NewFlateEncoder ());if _eee !=nil {continue ;};*_cgg =*_dca ;_cgg .Set ("\u004ce\u006e\u0067\u0074\u0068\u0031",_ba .MakeInteger (int64 (_ae .Len ())));};return objects ,nil ;};
    24  
    25  // CombineIdenticalIndirectObjects combines identical indirect objects.
    26  // It implements interface model.Optimizer.
    27  type CombineIdenticalIndirectObjects struct{};
    28  
    29  // Chain allows to use sequence of optimizers.
    30  // It implements interface model.Optimizer.
    31  type Chain struct{_fb []_cff .Optimizer };type objectStructure struct{_eefd *_ba .PdfObjectDictionary ;_fcdc *_ba .PdfObjectDictionary ;_ceg []*_ba .PdfIndirectObject ;};
    32  
    33  // CleanUnusedResources represents an optimizer used to clean unused resources.
    34  type CleanUnusedResources struct{};type imageInfo struct{BitsPerComponent int ;ColorComponents int ;Width int ;Height int ;Stream *_ba .PdfObjectStream ;PPI float64 ;};
    35  
    36  // CombineDuplicateStreams combines duplicated streams by its data hash.
    37  // It implements interface model.Optimizer.
    38  type CombineDuplicateStreams struct{};
    39  
    40  // ObjectStreams groups PDF objects to object streams.
    41  // It implements interface model.Optimizer.
    42  type ObjectStreams struct{};
    43  
    44  // Optimize optimizes PDF objects to decrease PDF size.
    45  func (_cb *CleanContentstream )Optimize (objects []_ba .PdfObject )(_gg []_ba .PdfObject ,_cgb error ){_cba :=map[*_ba .PdfObjectStream ]struct{}{};var _abe []*_ba .PdfObjectStream ;_ea :=func (_dd *_ba .PdfObjectStream ){if _ ,_bbea :=_cba [_dd ];!_bbea {_cba [_dd ]=struct{}{};
    46  _abe =append (_abe ,_dd );};};_gce :=map[_ba .PdfObject ]bool {};_af :=map[_ba .PdfObject ]bool {};for _ ,_fbe :=range objects {switch _bd :=_fbe .(type ){case *_ba .PdfIndirectObject :switch _fc :=_bd .PdfObject .(type ){case *_ba .PdfObjectDictionary :if _bfa ,_fef :=_ba .GetName (_fc .Get ("\u0054\u0079\u0070\u0065"));
    47  !_fef ||_bfa .String ()!="\u0050\u0061\u0067\u0065"{continue ;};if _fbeg ,_ddg :=_ba .GetStream (_fc .Get ("\u0043\u006f\u006e\u0074\u0065\u006e\u0074\u0073"));_ddg {_ea (_fbeg );}else if _efe ,_dad :=_ba .GetArray (_fc .Get ("\u0043\u006f\u006e\u0074\u0065\u006e\u0074\u0073"));
    48  _dad {var _ag []*_ba .PdfObjectStream ;for _ ,_eff :=range _efe .Elements (){if _bc ,_baa :=_ba .GetStream (_eff );_baa {_ag =append (_ag ,_bc );};};if len (_ag )> 0{var _fda _df .Buffer ;for _ ,_gga :=range _ag {if _eg ,_cbb :=_ba .DecodeStream (_gga );
    49  _cbb ==nil {_fda .Write (_eg );};_gce [_gga ]=true ;};_cbc ,_aag :=_ba .MakeStream (_fda .Bytes (),_ba .NewFlateEncoder ());if _aag !=nil {return nil ,_aag ;};_af [_cbc ]=true ;_fc .Set ("\u0043\u006f\u006e\u0074\u0065\u006e\u0074\u0073",_cbc );_ea (_cbc );
    50  };};};case *_ba .PdfObjectStream :if _adb ,_acb :=_ba .GetName (_bd .Get ("\u0054\u0079\u0070\u0065"));!_acb ||_adb .String ()!="\u0058O\u0062\u006a\u0065\u0063\u0074"{continue ;};if _bcd ,_gb :=_ba .GetName (_bd .Get ("\u0053u\u0062\u0074\u0079\u0070\u0065"));
    51  !_gb ||_bcd .String ()!="\u0046\u006f\u0072\u006d"{continue ;};_ea (_bd );};};for _ ,_cef :=range _abe {_cgb =_dc (_cef );if _cgb !=nil {return nil ,_cgb ;};};_gg =nil ;for _ ,_gbe :=range objects {if _gce [_gbe ]{continue ;};_gg =append (_gg ,_gbe );};
    52  for _eab :=range _af {_gg =append (_gg ,_eab );};return _gg ,nil ;};func _fbdb (_dga *_cff .Image ,_feb float64 )(*_cff .Image ,error ){_eac ,_ceed :=_dga .ToGoImage ();if _ceed !=nil {return nil ,_ceed ;};var _fbbd _fg .Image ;_fceed ,_agd :=_eac .(*_fg .Monochrome );
    53  if _agd {if _ceed =_fceed .ResolveDecode ();_ceed !=nil {return nil ,_ceed ;};_fbbd ,_ceed =_fceed .Scale (_feb );if _ceed !=nil {return nil ,_ceed ;};}else {_gbb :=int (_b .RoundToEven (float64 (_dga .Width )*_feb ));_deggg :=int (_b .RoundToEven (float64 (_dga .Height )*_feb ));
    54  _fbbd ,_ceed =_fg .NewImage (_gbb ,_deggg ,int (_dga .BitsPerComponent ),_dga .ColorComponents ,nil ,nil ,nil );if _ceed !=nil {return nil ,_ceed ;};_c .CatmullRom .Scale (_fbbd ,_fbbd .Bounds (),_eac ,_eac .Bounds (),_c .Over ,&_c .Options {});};_dfgg :=_fbbd .Base ();
    55  _cbce :=&_cff .Image {Width :int64 (_dfgg .Width ),Height :int64 (_dfgg .Height ),BitsPerComponent :int64 (_dfgg .BitsPerComponent ),ColorComponents :_dfgg .ColorComponents ,Data :_dfgg .Data };_cbce .SetDecode (_dfgg .Decode );_cbce .SetAlpha (_dfgg .Alpha );
    56  return _cbce ,nil ;};func _dc (_fe *_ba .PdfObjectStream )error {_de ,_da :=_ba .DecodeStream (_fe );if _da !=nil {return _da ;};_gd :=_bf .NewContentStreamParser (string (_de ));_baf ,_da :=_gd .Parse ();if _da !=nil {return _da ;};_baf =_gee (_baf );
    57  _bbe :=_baf .Bytes ();if len (_bbe )>=len (_de ){return nil ;};_ff ,_da :=_ba .MakeStream (_baf .Bytes (),_ba .NewFlateEncoder ());if _da !=nil {return _da ;};_fe .Stream =_ff .Stream ;_fe .Merge (_ff .PdfObjectDictionary );return nil ;};func _bfd (_fage []_ba .PdfObject )objectStructure {_ccdb :=objectStructure {};
    58  _fffgc :=false ;for _ ,_geef :=range _fage {switch _eggg :=_geef .(type ){case *_ba .PdfIndirectObject :_gagc ,_feae :=_ba .GetDict (_eggg );if !_feae {continue ;};_geaf ,_feae :=_ba .GetName (_gagc .Get ("\u0054\u0079\u0070\u0065"));if !_feae {continue ;
    59  };switch _geaf .String (){case "\u0043a\u0074\u0061\u006c\u006f\u0067":_ccdb ._eefd =_gagc ;_fffgc =true ;};};if _fffgc {break ;};};if !_fffgc {return _ccdb ;};_dbf ,_aff :=_ba .GetDict (_ccdb ._eefd .Get ("\u0050\u0061\u0067e\u0073"));if !_aff {return _ccdb ;
    60  };_ccdb ._fcdc =_dbf ;_cadb ,_aff :=_ba .GetArray (_dbf .Get ("\u004b\u0069\u0064\u0073"));if !_aff {return _ccdb ;};for _ ,_bcbf :=range _cadb .Elements (){_ceaf ,_bage :=_ba .GetIndirect (_bcbf );if !_bage {break ;};_ccdb ._ceg =append (_ccdb ._ceg ,_ceaf );
    61  };return _ccdb ;};
    62  
    63  // CleanFonts cleans up embedded fonts, reducing font sizes.
    64  type CleanFonts struct{
    65  
    66  // Subset embedded fonts if encountered (if true).
    67  // Otherwise attempts to reduce the font program.
    68  Subset bool ;};
    69  
    70  // Optimize optimizes PDF objects to decrease PDF size.
    71  func (_edbd *CombineIdenticalIndirectObjects )Optimize (objects []_ba .PdfObject )(_dcf []_ba .PdfObject ,_ddab error ){_cfgcg (objects );_ega :=make (map[_ba .PdfObject ]_ba .PdfObject );_egg :=make (map[_ba .PdfObject ]struct{});_cbbd :=make (map[string ][]*_ba .PdfIndirectObject );
    72  for _ ,_acbc :=range objects {_acda ,_cfc :=_acbc .(*_ba .PdfIndirectObject );if !_cfc {continue ;};if _fac ,_bdf :=_acda .PdfObject .(*_ba .PdfObjectDictionary );_bdf {if _eeef ,_cgc :=_fac .Get ("\u0054\u0079\u0070\u0065").(*_ba .PdfObjectName );_cgc &&*_eeef =="\u0050\u0061\u0067\u0065"{continue ;
    73  };_eaa :=_ce .New ();_eaa .Write ([]byte (_fac .WriteString ()));_agfb :=string (_eaa .Sum (nil ));_cbbd [_agfb ]=append (_cbbd [_agfb ],_acda );};};for _ ,_aed :=range _cbbd {if len (_aed )< 2{continue ;};_gfc :=_aed [0];for _effc :=1;_effc < len (_aed );
    74  _effc ++{_bba :=_aed [_effc ];_ega [_bba ]=_gfc ;_egg [_bba ]=struct{}{};};};_dcf =make ([]_ba .PdfObject ,0,len (objects )-len (_egg ));for _ ,_abgd :=range objects {if _ ,_abec :=_egg [_abgd ];_abec {continue ;};_dcf =append (_dcf ,_abgd );};_gdgd (_dcf ,_ega );
    75  return _dcf ,nil ;};
    76  
    77  // ImagePPI optimizes images by scaling images such that the PPI (pixels per inch) is never higher than ImageUpperPPI.
    78  // TODO(a5i): Add support for inline images.
    79  // It implements interface model.Optimizer.
    80  type ImagePPI struct{ImageUpperPPI float64 ;};
    81  
    82  // CombineDuplicateDirectObjects combines duplicated direct objects by its data hash.
    83  // It implements interface model.Optimizer.
    84  type CombineDuplicateDirectObjects struct{};
    85  
    86  // Image optimizes images by rewrite images into JPEG format with quality equals to ImageQuality.
    87  // TODO(a5i): Add support for inline images.
    88  // It implements interface model.Optimizer.
    89  type Image struct{ImageQuality int ;};func _gee (_ad *_bf .ContentStreamOperations )*_bf .ContentStreamOperations {if _ad ==nil {return nil ;};_fd :=_bf .ContentStreamOperations {};for _ ,_gfg :=range *_ad {switch _gfg .Operand {case "\u0042\u0044\u0043","\u0042\u004d\u0043","\u0045\u004d\u0043":continue ;
    90  case "\u0054\u006d":if len (_gfg .Params )==6{if _fde ,_aa :=_ba .GetNumbersAsFloat (_gfg .Params );_aa ==nil {if _fde [0]==1&&_fde [1]==0&&_fde [2]==0&&_fde [3]==1{_gfg =&_bf .ContentStreamOperation {Params :[]_ba .PdfObject {_gfg .Params [4],_gfg .Params [5]},Operand :"\u0054\u0064"};
    91  };};};};_fd =append (_fd ,_gfg );};return &_fd ;};
    92  
    93  // CleanContentstream cleans up redundant operands in content streams, including Page and XObject Form
    94  // contents. This process includes:
    95  // 1. Marked content operators are removed.
    96  // 2. Some operands are simplified (shorter form).
    97  // TODO: Add more reduction methods and improving the methods for identifying unnecessary operands.
    98  type CleanContentstream struct{};
    99  
   100  // Optimize optimizes PDF objects to decrease PDF size.
   101  func (_fae *CompressStreams )Optimize (objects []_ba .PdfObject )(_agab []_ba .PdfObject ,_cdfg error ){_agab =make ([]_ba .PdfObject ,len (objects ));copy (_agab ,objects );for _ ,_ddgf :=range objects {_cefe ,_gaga :=_ba .GetStream (_ddgf );if !_gaga {continue ;
   102  };if _agaa :=_cefe .Get ("\u0046\u0069\u006c\u0074\u0065\u0072");_agaa !=nil {if _ ,_dgcb :=_ba .GetName (_agaa );_dgcb {continue ;};if _ebf ,_ggcc :=_ba .GetArray (_agaa );_ggcc &&_ebf .Len ()> 0{continue ;};};_dag :=_ba .NewFlateEncoder ();var _ccdf []byte ;
   103  _ccdf ,_cdfg =_dag .EncodeBytes (_cefe .Stream );if _cdfg !=nil {return _agab ,_cdfg ;};_ebb :=_dag .MakeStreamDict ();if len (_ccdf )+len (_ebb .WriteString ())< len (_cefe .Stream ){_cefe .Stream =_ccdf ;_cefe .PdfObjectDictionary .Merge (_ebb );_cefe .PdfObjectDictionary .Set ("\u004c\u0065\u006e\u0067\u0074\u0068",_ba .MakeInteger (int64 (len (_cefe .Stream ))));
   104  };};return _agab ,nil ;};func _gdac (_bdc _ba .PdfObject )(_afdg string ,_bfbb []_ba .PdfObject ){var _aeafb _df .Buffer ;switch _eefb :=_bdc .(type ){case *_ba .PdfIndirectObject :_bfbb =append (_bfbb ,_eefb );_bdc =_eefb .PdfObject ;};switch _bccb :=_bdc .(type ){case *_ba .PdfObjectStream :if _acbe ,_gdc :=_ba .DecodeStream (_bccb );
   105  _gdc ==nil {_aeafb .Write (_acbe );_bfbb =append (_bfbb ,_bccb );};case *_ba .PdfObjectArray :for _ ,_cadc :=range _bccb .Elements (){switch _abgb :=_cadc .(type ){case *_ba .PdfObjectStream :if _eeed ,_bfeeg :=_ba .DecodeStream (_abgb );_bfeeg ==nil {_aeafb .Write (_eeed );
   106  _bfbb =append (_bfbb ,_abgb );};};};};return _aeafb .String (),_bfbb ;};
   107  
   108  // Optimize optimizes PDF objects to decrease PDF size.
   109  func (_eb *Chain )Optimize (objects []_ba .PdfObject )(_ed []_ba .PdfObject ,_gf error ){_cg :=objects ;for _ ,_cd :=range _eb ._fb {_dfb ,_cdf :=_cd .Optimize (_cg );if _cdf !=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",_cdf );
   110  continue ;};_cg =_dfb ;};return _cg ,nil ;};func _edg (_bcc *_ba .PdfObjectStream ,_dfg []rune ,_ggg []_gc .GlyphIndex )error {_bcc ,_caf :=_ba .GetStream (_bcc );if !_caf {_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");
   111  return _e .New ("\u0066\u006f\u006e\u0074fi\u006c\u0065\u0032\u0020\u006e\u006f\u0074\u0020\u0066\u006f\u0075\u006e\u0064");};_cgf ,_bbd :=_ba .DecodeStream (_bcc );if _bbd !=nil {_f .Log .Debug ("\u0044\u0065c\u006f\u0064\u0065 \u0065\u0072\u0072\u006f\u0072\u003a\u0020\u0025\u0076",_bbd );
   112  return _bbd ;};_cbg ,_bbd :=_gc .Parse (_df .NewReader (_cgf ));if _bbd !=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 (_bcc .Stream ));
   113  return _bbd ;};_cfg :=_ggg ;if len (_dfg )> 0{_gbc :=_cbg .LookupRunes (_dfg );_cfg =append (_cfg ,_gbc ...);};_cbg ,_bbd =_cbg .SubsetKeepIndices (_cfg );if _bbd !=nil {_f .Log .Debug ("\u0045R\u0052\u004f\u0052\u0020s\u0075\u0062\u0073\u0065\u0074t\u0069n\u0067 \u0066\u006f\u006e\u0074\u003a\u0020\u0025v",_bbd );
   114  return _bbd ;};var _gda _df .Buffer ;_bbd =_cbg .Write (&_gda );if _bbd !=nil {_f .Log .Debug ("\u0045\u0052\u0052\u004fR \u0057\u0072\u0069\u0074\u0069\u006e\u0067\u0020\u0066\u006f\u006e\u0074\u003a\u0020%\u0076",_bbd );return _bbd ;};if _gda .Len ()> len (_cgf ){_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");
   115  return nil ;};_gfb ,_bbd :=_ba .MakeStream (_gda .Bytes (),_ba .NewFlateEncoder ());if _bbd !=nil {_f .Log .Debug ("\u0045\u0052\u0052\u004fR \u0057\u0072\u0069\u0074\u0069\u006e\u0067\u0020\u0066\u006f\u006e\u0074\u003a\u0020%\u0076",_bbd );return _bbd ;
   116  };*_bcc =*_gfb ;_bcc .Set ("\u004ce\u006e\u0067\u0074\u0068\u0031",_ba .MakeInteger (int64 (_gda .Len ())));return nil ;};
   117  
   118  // New creates a optimizers chain from options.
   119  func New (options Options )*Chain {_gbdb :=new (Chain );if options .CleanFonts ||options .SubsetFonts {_gbdb .Append (&CleanFonts {Subset :options .SubsetFonts });};if options .CleanContentstream {_gbdb .Append (new (CleanContentstream ));};if options .ImageUpperPPI > 0{_aedf :=new (ImagePPI );
   120  _aedf .ImageUpperPPI =options .ImageUpperPPI ;_gbdb .Append (_aedf );};if options .ImageQuality > 0{_bbeg :=new (Image );_bbeg .ImageQuality =options .ImageQuality ;_gbdb .Append (_bbeg );};if options .CombineDuplicateDirectObjects {_gbdb .Append (new (CombineDuplicateDirectObjects ));
   121  };if options .CombineDuplicateStreams {_gbdb .Append (new (CombineDuplicateStreams ));};if options .CombineIdenticalIndirectObjects {_gbdb .Append (new (CombineIdenticalIndirectObjects ));};if options .UseObjectStreams {_gbdb .Append (new (ObjectStreams ));
   122  };if options .CompressStreams {_gbdb .Append (new (CompressStreams ));};if options .CleanUnusedResources {_gbdb .Append (new (CleanUnusedResources ));};return _gbdb ;};
   123  
   124  // Optimize optimizes PDF objects to decrease PDF size.
   125  func (_ceaa *CombineDuplicateDirectObjects )Optimize (objects []_ba .PdfObject )(_adc []_ba .PdfObject ,_ffc error ){_cfgcg (objects );_aea :=make (map[string ][]*_ba .PdfObjectDictionary );var _gdab func (_efg *_ba .PdfObjectDictionary );_gdab =func (_gdff *_ba .PdfObjectDictionary ){for _ ,_fffg :=range _gdff .Keys (){_daf :=_gdff .Get (_fffg );
   126  if _dda ,_ffd :=_daf .(*_ba .PdfObjectDictionary );_ffd {_bcf :=_ce .New ();_bcf .Write ([]byte (_dda .WriteString ()));_dee :=string (_bcf .Sum (nil ));_aea [_dee ]=append (_aea [_dee ],_dda );_gdab (_dda );};};};for _ ,_eec :=range objects {_agbf ,_gcfc :=_eec .(*_ba .PdfIndirectObject );
   127  if !_gcfc {continue ;};if _daca ,_afb :=_agbf .PdfObject .(*_ba .PdfObjectDictionary );_afb {_gdab (_daca );};};_bfee :=make ([]_ba .PdfObject ,0,len (_aea ));_ded :=make (map[_ba .PdfObject ]_ba .PdfObject );for _ ,_aeb :=range _aea {if len (_aeb )< 2{continue ;
   128  };_ggbf :=_ba .MakeDict ();_ggbf .Merge (_aeb [0]);_ada :=_ba .MakeIndirectObject (_ggbf );_bfee =append (_bfee ,_ada );for _bcff :=0;_bcff < len (_aeb );_bcff ++{_ggcf :=_aeb [_bcff ];_ded [_ggcf ]=_ada ;};};_adc =make ([]_ba .PdfObject ,len (objects ));
   129  copy (_adc ,objects );_adc =append (_bfee ,_adc ...);_gdgd (_adc ,_ded );return _adc ,nil ;};func _cad (_bffe string ,_feg []string )bool {for _ ,_gdg :=range _feg {if _bffe ==_gdg {return true ;};};return false ;};func _eabg (_aeg []*_ba .PdfIndirectObject )map[string ][]string {_bdga :=map[string ][]string {};
   130  for _ ,_ffe :=range _aeg {_dgg ,_gdaa :=_ba .GetDict (_ffe .PdfObject );if !_gdaa {continue ;};_efea :=_dgg .Get ("\u0043\u006f\u006e\u0074\u0065\u006e\u0074\u0073");_cag :=_ba .TraceToDirectObject (_efea );var _bgb []string ;if _eeb ,_agc :=_cag .(*_ba .PdfObjectArray );
   131  _agc {for _ ,_ffeg :=range _eeb .Elements (){_afe ,_ffa :=_eeg (_ffeg );if _ffa !=nil {continue ;};_bgb =append (_bgb ,_afe );};};_gfe :=_a .Join (_bgb ,"\u0020");_beg :=_bf .NewContentStreamParser (_gfe );_geb ,_feeb :=_beg .Parse ();if _feeb !=nil {continue ;
   132  };for _ ,_ebe :=range *_geb {_gage :=_ebe .Operand ;_cbad :=_ebe .Params ;switch _gage {case "\u0044\u006f":_ggf :=_cbad [0].String ();if _ ,_dcaa :=_bdga ["\u0058O\u0062\u006a\u0065\u0063\u0074"];!_dcaa {_bdga ["\u0058O\u0062\u006a\u0065\u0063\u0074"]=[]string {_ggf };
   133  }else {_bdga ["\u0058O\u0062\u006a\u0065\u0063\u0074"]=append (_bdga ["\u0058O\u0062\u006a\u0065\u0063\u0074"],_ggf );};case "\u0054\u0066":_gcda :=_cbad [0].String ();if _ ,_abf :=_bdga ["\u0046\u006f\u006e\u0074"];!_abf {_bdga ["\u0046\u006f\u006e\u0074"]=[]string {_gcda };
   134  }else {_bdga ["\u0046\u006f\u006e\u0074"]=append (_bdga ["\u0046\u006f\u006e\u0074"],_gcda );};case "\u0067\u0073":_ecgb :=_cbad [0].String ();if _ ,_dccd :=_bdga ["\u0045x\u0074\u0047\u0053\u0074\u0061\u0074e"];!_dccd {_bdga ["\u0045x\u0074\u0047\u0053\u0074\u0061\u0074e"]=[]string {_ecgb };
   135  }else {_bdga ["\u0045x\u0074\u0047\u0053\u0074\u0061\u0074e"]=append (_bdga ["\u0045x\u0074\u0047\u0053\u0074\u0061\u0074e"],_ecgb );};};};};return _bdga ;};func _egf (_gde []_ba .PdfObject )(_fca map[*_ba .PdfObjectStream ]struct{},_aagg error ){_fca =map[*_ba .PdfObjectStream ]struct{}{};
   136  _fff :=map[*_cff .PdfFont ]struct{}{};_fbd :=_bfd (_gde );for _ ,_aga :=range _fbd ._ceg {_ffb ,_efee :=_ba .GetDict (_aga .PdfObject );if !_efee {continue ;};_cdb ,_efee :=_ba .GetDict (_ffb .Get ("\u0052e\u0073\u006f\u0075\u0072\u0063\u0065s"));if !_efee {continue ;
   137  };_agb ,_ :=_gdac (_ffb .Get ("\u0043\u006f\u006e\u0074\u0065\u006e\u0074\u0073"));_egfg ,_be :=_cff .NewPdfPageResourcesFromDict (_cdb );if _be !=nil {return nil ,_be ;};_bee :=[]content {{_gab :_agb ,_fga :_egfg }};_fce :=_ccf (_ffb .Get ("\u0041\u006e\u006e\u006f\u0074\u0073"));
   138  if _fce !=nil {_bee =append (_bee ,_fce ...);};for _ ,_gcf :=range _bee {_egff ,_bae :=_d .NewFromContents (_gcf ._gab ,_gcf ._fga );if _bae !=nil {return nil ,_bae ;};_cgd ,_ ,_ ,_bae :=_egff .ExtractPageText ();if _bae !=nil {return nil ,_bae ;};for _ ,_fcc :=range _cgd .Marks ().Elements (){if _fcc .Font ==nil {continue ;
   139  };if _ ,_db :=_fff [_fcc .Font ];!_db {_fff [_fcc .Font ]=struct{}{};};};};};_fee :=map[*_ba .PdfObjectStream ][]*_cff .PdfFont {};for _ecb :=range _fff {_cc :=_ecb .FontDescriptor ();if _cc ==nil ||_cc .FontFile2 ==nil {continue ;};_fceg ,_bcb :=_ba .GetStream (_cc .FontFile2 );
   140  if !_bcb {continue ;};_fee [_fceg ]=append (_fee [_fceg ],_ecb );};for _gcg :=range _fee {var _dcd []rune ;var _abc []_gc .GlyphIndex ;for _ ,_gcee :=range _fee [_gcg ]{switch _aab :=_gcee .Encoder ().(type ){case *_cf .IdentityEncoder :_cee :=_aab .RegisteredRunes ();
   141  _dbb :=make ([]_gc .GlyphIndex ,len (_cee ));for _bfe ,_bab :=range _cee {_dbb [_bfe ]=_gc .GlyphIndex (_bab );};_abc =append (_abc ,_dbb ...);case *_cf .TrueTypeFontEncoder :_ccd :=_aab .RegisteredRunes ();_dcd =append (_dcd ,_ccd ...);case _cf .SimpleEncoder :_cbaf :=_aab .Charcodes ();
   142  for _ ,_ca :=range _cbaf {_ddc ,_egd :=_aab .CharcodeToRune (_ca );if !_egd {_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",_ca );
   143  continue ;};_dcd =append (_dcd ,_ddc );};};};_aagg =_edg (_gcg ,_dcd ,_abc );if _aagg !=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",_aagg );
   144  return nil ,_aagg ;};_fca [_gcg ]=struct{}{};};return _fca ,nil ;};
   145  
   146  // Optimize implements Optimizer interface.
   147  func (_ged *CleanUnusedResources )Optimize (objects []_ba .PdfObject )(_bgg []_ba .PdfObject ,_bac error ){_ddcd ,_bac :=_ade (objects );if _bac !=nil {return nil ,_bac ;};_aba :=[]_ba .PdfObject {};for _ ,_dgd :=range objects {_ ,_bfac :=_ddcd [_dgd ];
   148  if _bfac {continue ;};_aba =append (_aba ,_dgd );};return _aba ,nil ;};func _edb (_gca *_ba .PdfObjectDictionary )[]string {_fgee :=[]string {};for _ ,_dbgb :=range _gca .Keys (){_fgee =append (_fgee ,_dbgb .String ());};return _fgee ;};func _ebaa (_dcg []_ba .PdfObject )[]*imageInfo {_fgg :=_ba .PdfObjectName ("\u0053u\u0062\u0074\u0079\u0070\u0065");
   149  _ffea :=make (map[*_ba .PdfObjectStream ]struct{});var _babd []*imageInfo ;for _ ,_aebg :=range _dcg {_bfg ,_eaac :=_ba .GetStream (_aebg );if !_eaac {continue ;};if _ ,_aeac :=_ffea [_bfg ];_aeac {continue ;};_ffea [_bfg ]=struct{}{};_ddb :=_bfg .PdfObjectDictionary .Get (_fgg );
   150  _gbgd ,_eaac :=_ba .GetName (_ddb );if !_eaac ||string (*_gbgd )!="\u0049\u006d\u0061g\u0065"{continue ;};_ebec :=&imageInfo {Stream :_bfg ,BitsPerComponent :8};if _bbdd ,_gbeb :=_ba .GetIntVal (_bfg .Get ("\u0042\u0069t\u0073\u0050\u0065r\u0043\u006f\u006d\u0070\u006f\u006e\u0065\u006e\u0074"));
   151  _gbeb {_ebec .BitsPerComponent =_bbdd ;};if _gagb ,_bdb :=_ba .GetIntVal (_bfg .Get ("\u0057\u0069\u0064t\u0068"));_bdb {_ebec .Width =_gagb ;};if _bbbf ,_cbd :=_ba .GetIntVal (_bfg .Get ("\u0048\u0065\u0069\u0067\u0068\u0074"));_cbd {_ebec .Height =_bbbf ;
   152  };_gabed ,_ggbd :=_cff .NewPdfColorspaceFromPdfObject (_bfg .Get ("\u0043\u006f\u006c\u006f\u0072\u0053\u0070\u0061\u0063\u0065"));if _ggbd !=nil {_f .Log .Debug ("\u0045R\u0052\u004f\u0052\u003a\u0020\u0025v",_ggbd );continue ;};if _gabed ==nil {_ccg ,_ecdg :=_ba .GetName (_bfg .Get ("\u0046\u0069\u006c\u0074\u0065\u0072"));
   153  if _ecdg {switch _ccg .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":_gabed =_cff .NewPdfColorspaceDeviceGray ();_ebec .BitsPerComponent =1;
   154  };};};switch _ebac :=_gabed .(type ){case *_cff .PdfColorspaceDeviceRGB :_ebec .ColorComponents =3;case *_cff .PdfColorspaceDeviceGray :_ebec .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",_ebac );
   155  continue ;};_babd =append (_babd ,_ebec );};return _babd ;};func _ade (_cbgb []_ba .PdfObject )(map[_ba .PdfObject ]struct{},error ){_cae :=_bfd (_cbgb );_aaa :=_cae ._ceg ;_fba :=make (map[_ba .PdfObject ]struct{});_gcc :=_eabg (_aaa );for _ ,_cfbf :=range _aaa {_bdg ,_cdfd :=_ba .GetDict (_cfbf .PdfObject );
   156  if !_cdfd {continue ;};_bfae ,_cdfd :=_ba .GetDict (_bdg .Get ("\u0052e\u0073\u006f\u0075\u0072\u0063\u0065s"));if !_cdfd {continue ;};_cfd :=_gcc ["\u0058O\u0062\u006a\u0065\u0063\u0074"];_cdd ,_cdfd :=_ba .GetDict (_bfae .Get ("\u0058O\u0062\u006a\u0065\u0063\u0074"));
   157  if _cdfd {_dbg :=_edb (_cdd );for _ ,_dbe :=range _dbg {if _cad (_dbe ,_cfd ){continue ;};_gdb :=*_ba .MakeName (_dbe );_acc :=_cdd .Get (_gdb );_fba [_acc ]=struct{}{};_cdd .Remove (_gdb );_fbaa :=_gcdb (_acc ,_fba );if _fbaa !=nil {_f .Log .Debug ("\u0066\u0061\u0069\u006ce\u0064\u0020\u0074\u006f\u0020\u0074\u0072\u0061\u0076\u0065r\u0073e\u0020\u006f\u0062\u006a\u0065\u0063\u0074 \u0025\u0076",_acc );
   158  };};};_dab ,_cdfd :=_ba .GetDict (_bfae .Get ("\u0046\u006f\u006e\u0074"));_fcf :=_gcc ["\u0046\u006f\u006e\u0074"];if _cdfd {_eeee :=_edb (_dab );for _ ,_gac :=range _eeee {if _cad (_gac ,_fcf ){continue ;};_fddc :=*_ba .MakeName (_gac );_ggc :=_dab .Get (_fddc );
   159  _fba [_ggc ]=struct{}{};_dab .Remove (_fddc );_geda :=_gcdb (_ggc ,_fba );if _geda !=nil {_f .Log .Debug ("\u0046\u0061i\u006c\u0065\u0064\u0020\u0074\u006f\u0020\u0074\u0072\u0061\u0076\u0065\u0072\u0073\u0065\u0020\u006f\u0062\u006a\u0065\u0063\u0074 %\u0076\u000a",_ggc );
   160  };};};_cdc ,_cdfd :=_ba .GetDict (_bfae .Get ("\u0045x\u0074\u0047\u0053\u0074\u0061\u0074e"));if _cdfd {_bda :=_edb (_cdc );_cbe :=_gcc ["\u0045x\u0074\u0047\u0053\u0074\u0061\u0074e"];for _ ,_dcba :=range _bda {if _cad (_dcba ,_cbe ){continue ;};_gefg :=*_ba .MakeName (_dcba );
   161  _gdf :=_cdc .Get (_gefg );_fba [_gdf ]=struct{}{};_cdc .Remove (_gefg );_gbcb :=_gcdb (_gdf ,_fba );if _gbcb !=nil {_f .Log .Debug ("\u0066\u0061i\u006c\u0065\u0064\u0020\u0074\u006f\u0020\u0074\u0072\u0061\u0076\u0065\u0072\u0073\u0065\u0020\u006f\u0062\u006a\u0065\u0063\u0074 %\u0076\u000a",_gdf );
   162  };};};};return _fba ,nil ;};func _eeg (_age _ba .PdfObject )(string ,error ){_bdgaf :=_ba .TraceToDirectObject (_age );switch _afa :=_bdgaf .(type ){case *_ba .PdfObjectString :return _afa .Str (),nil ;case *_ba .PdfObjectStream :_bfb ,_fge :=_ba .DecodeStream (_afa );
   163  if _fge !=nil {return "",_fge ;};return string (_bfb ),nil ;};return "",_ac .Errorf ("\u0069\u006e\u0076\u0061\u006ci\u0064\u0020\u0063\u006f\u006e\u0074\u0065\u006e\u0074\u0020\u0073\u0074\u0072e\u0061\u006d\u0020\u006f\u0062\u006a\u0065\u0063\u0074\u0020\u0068\u006f\u006c\u0064\u0065\u0072\u0020\u0028\u0025\u0054\u0029",_bdgaf );
   164  };func _cfgcg (_fccgb []_ba .PdfObject ){for _ggbfb ,_acf :=range _fccgb {switch _geeb :=_acf .(type ){case *_ba .PdfIndirectObject :_geeb .ObjectNumber =int64 (_ggbfb +1);_geeb .GenerationNumber =0;case *_ba .PdfObjectStream :_geeb .ObjectNumber =int64 (_ggbfb +1);
   165  _geeb .GenerationNumber =0;case *_ba .PdfObjectStreams :_geeb .ObjectNumber =int64 (_ggbfb +1);_geeb .GenerationNumber =0;};};};type imageModifications struct{Scale float64 ;Encoding _ba .StreamEncoder ;};func _ccf (_bec _ba .PdfObject )[]content {if _bec ==nil {return nil ;
   166  };_ecd ,_gag :=_ba .GetArray (_bec );if !_gag {_f .Log .Debug ("\u0041\u006e\u006e\u006fts\u0020\u006e\u006f\u0074\u0020\u0061\u006e\u0020\u0061\u0072\u0072\u0061\u0079");return nil ;};var _fdd []content ;for _ ,_eef :=range _ecd .Elements (){_baaf ,_dccb :=_ba .GetDict (_eef );
   167  if !_dccb {_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 ;};_bgc ,_dccb :=_ba .GetDict (_baaf .Get ("\u0041\u0050"));
   168  if !_dccb {_f .Log .Debug ("\u004e\u006f\u0020\u0041P \u0065\u006e\u0074\u0072\u0079\u0020\u002d\u0020\u0073\u006b\u0069\u0070\u0070\u0069n\u0067");continue ;};_efc :=_ba .TraceToDirectObject (_bgc .Get ("\u004e"));if _efc ==nil {_f .Log .Debug ("N\u006f\u0020\u004e\u0020en\u0074r\u0079\u0020\u002d\u0020\u0073k\u0069\u0070\u0070\u0069\u006e\u0067");
   169  continue ;};var _dg *_ba .PdfObjectStream ;switch _eda :=_efc .(type ){case *_ba .PdfObjectDictionary :_deg ,_fea :=_ba .GetName (_baaf .Get ("\u0041\u0053"));if !_fea {_f .Log .Debug ("\u004e\u006f\u0020\u0041S \u0065\u006e\u0074\u0072\u0079\u0020\u002d\u0020\u0073\u006b\u0069\u0070\u0070\u0069n\u0067");
   170  continue ;};_dg ,_fea =_ba .GetStream (_eda .Get (*_deg ));if !_fea {_f .Log .Debug ("\u0046o\u0072\u006d\u0020\u006eo\u0074\u0020\u0066\u006f\u0075n\u0064 \u002d \u0073\u006b\u0069\u0070\u0070\u0069\u006eg");continue ;};case *_ba .PdfObjectStream :_dg =_eda ;
   171  };if _dg ==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 ;};_ecg ,_eabd :=_cff .NewXObjectFormFromStream (_dg );
   172  if _eabd !=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",_eabd );continue ;};_ace ,_eabd :=_ecg .GetContentStream ();
   173  if _eabd !=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",_eabd );continue ;};_fdd =append (_fdd ,content {_gab :string (_ace ),_fga :_ecg .Resources });
   174  };return _fdd ;};
   175  
   176  // Optimize optimizes PDF objects to decrease PDF size.
   177  func (_eaaa *ImagePPI )Optimize (objects []_ba .PdfObject )(_fcaa []_ba .PdfObject ,_fbcf error ){if _eaaa .ImageUpperPPI <=0{return objects ,nil ;};_cbadc :=_ebaa (objects );if len (_cbadc )==0{return objects ,nil ;};_fgac :=make (map[_ba .PdfObject ]struct{});
   178  for _ ,_gggc :=range _cbadc {_bag :=_gggc .Stream .PdfObjectDictionary .Get ("\u0053\u004d\u0061s\u006b");_fgac [_bag ]=struct{}{};};_cgca :=make (map[*_ba .PdfObjectStream ]*imageInfo );for _ ,_ddbd :=range _cbadc {_cgca [_ddbd .Stream ]=_ddbd ;};var _efd *_ba .PdfObjectDictionary ;
   179  for _ ,_dbde :=range objects {if _fdea ,_gdgb :=_ba .GetDict (_dbde );_efd ==nil &&_gdgb {if _bccg ,_aaaa :=_ba .GetName (_fdea .Get ("\u0054\u0079\u0070\u0065"));_aaaa &&*_bccg =="\u0043a\u0074\u0061\u006c\u006f\u0067"{_efd =_fdea ;};};};if _efd ==nil {return objects ,nil ;
   180  };_gabg ,_efb :=_ba .GetDict (_efd .Get ("\u0050\u0061\u0067e\u0073"));if !_efb {return objects ,nil ;};_eeeea ,_eecf :=_ba .GetArray (_gabg .Get ("\u004b\u0069\u0064\u0073"));if !_eecf {return objects ,nil ;};for _ ,_gece :=range _eeeea .Elements (){_ddd :=make (map[string ]*imageInfo );
   181  _aad ,_deb :=_ba .GetDict (_gece );if !_deb {continue ;};_fbg ,_ :=_gdac (_aad .Get ("\u0043\u006f\u006e\u0074\u0065\u006e\u0074\u0073"));if len (_fbg )==0{continue ;};_effb ,_cge :=_ba .GetDict (_aad .Get ("\u0052e\u0073\u006f\u0075\u0072\u0063\u0065s"));
   182  if !_cge {continue ;};_ebdb ,_gcac :=_cff .NewPdfPageResourcesFromDict (_effb );if _gcac !=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",_gcac );
   183  continue ;};_gabb ,_bacg :=_ba .GetDict (_effb .Get ("\u0058O\u0062\u006a\u0065\u0063\u0074"));if !_bacg {continue ;};_dba :=_gabb .Keys ();for _ ,_gbf :=range _dba {if _efebf ,_bca :=_ba .GetStream (_gabb .Get (_gbf ));_bca {if _defc ,_gbgg :=_cgca [_efebf ];
   184  _gbgg {_ddd [string (_gbf )]=_defc ;};};};_dgdg :=_bf .NewContentStreamParser (_fbg );_afbc ,_gcac :=_dgdg .Parse ();if _gcac !=nil {_f .Log .Debug ("\u0045\u0052\u0052\u004f\u0052\u003a\u0020\u0025\u002b\u0076",_gcac );continue ;};_deee :=_bf .NewContentStreamProcessor (*_afbc );
   185  _deee .AddHandler (_bf .HandlerConditionEnumAllOperands ,"",func (_bdff *_bf .ContentStreamOperation ,_bece _bf .GraphicsState ,_acca *_cff .PdfPageResources )error {switch _bdff .Operand {case "\u0044\u006f":if len (_bdff .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");
   186  return nil ;};_bacgc ,_cfa :=_ba .GetName (_bdff .Params [0]);if !_cfa {_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");
   187  return nil ;};if _eaeg ,_cfcg :=_ddd [string (*_bacgc )];_cfcg {_gdd :=_bece .CTM .ScalingFactorX ();_faf :=_bece .CTM .ScalingFactorY ();_fgd ,_bge :=_gdd /72.0,_faf /72.0;_gfab ,_gebb :=float64 (_eaeg .Width )/_fgd ,float64 (_eaeg .Height )/_bge ;if _fgd ==0||_bge ==0{_gfab =72.0;
   188  _gebb =72.0;};_eaeg .PPI =_b .Max (_eaeg .PPI ,_gfab );_eaeg .PPI =_b .Max (_eaeg .PPI ,_gebb );};};return nil ;});_gcac =_deee .Process (_ebdb );if _gcac !=nil {_f .Log .Debug ("E\u0052\u0052\u004f\u0052 p\u0072o\u0063\u0065\u0073\u0073\u0069n\u0067\u003a\u0020\u0025\u002b\u0076",_gcac );
   189  continue ;};};for _ ,_cffa :=range _cbadc {if _ ,_fccbe :=_fgac [_cffa .Stream ];_fccbe {continue ;};if _cffa .PPI <=_eaaa .ImageUpperPPI {continue ;};_gge ,_aebe :=_cff .NewXObjectImageFromStream (_cffa .Stream );if _aebe !=nil {_f .Log .Debug ("\u0045\u0052\u0052\u004f\u0052\u003a\u0020\u0025\u002b\u0076",_aebe );
   190  continue ;};var _fag imageModifications ;_fag .Scale =_eaaa .ImageUpperPPI /_cffa .PPI ;if _cffa .BitsPerComponent ==1&&_cffa .ColorComponents ==1{_bdgaa :=_b .Round (_cffa .PPI /_eaaa .ImageUpperPPI );_cfgc :=_fg .NextPowerOf2 (uint (_bdgaa ));if _fg .InDelta (float64 (_cfgc ),1/_fag .Scale ,0.3){_fag .Scale =float64 (1)/float64 (_cfgc );
   191  };if _ ,_abfa :=_gge .Filter .(*_ba .JBIG2Encoder );!_abfa {_fag .Encoding =_ba .NewJBIG2Encoder ();};};if _aebe =_gbd (_gge ,_fag );_aebe !=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",_aebe );
   192  continue ;};_fag .Encoding =nil ;if _aebb ,_dacg :=_ba .GetStream (_cffa .Stream .PdfObjectDictionary .Get ("\u0053\u004d\u0061s\u006b"));_dacg {_gff ,_gfae :=_cff .NewXObjectImageFromStream (_aebb );if _gfae !=nil {_f .Log .Debug ("\u0045\u0052\u0052\u004f\u0052\u003a\u0020\u0025\u002b\u0076",_gfae );
   193  continue ;};if _gfae =_gbd (_gff ,_fag );_gfae !=nil {_f .Log .Debug ("\u0045\u0052\u0052\u004f\u0052\u003a\u0020\u0025\u002b\u0076",_gfae );continue ;};};};return objects ,nil ;};func _gdgd (_caeg []_ba .PdfObject ,_ecc map[_ba .PdfObject ]_ba .PdfObject ){if len (_ecc )==0{return ;
   194  };for _gccb ,_ceeg :=range _caeg {if _gfag ,_fgeda :=_ecc [_ceeg ];_fgeda {_caeg [_gccb ]=_gfag ;continue ;};_ecc [_ceeg ]=_ceeg ;switch _bbfdg :=_ceeg .(type ){case *_ba .PdfObjectArray :_aeaf :=make ([]_ba .PdfObject ,_bbfdg .Len ());copy (_aeaf ,_bbfdg .Elements ());
   195  _gdgd (_aeaf ,_ecc );for _adg ,_gcef :=range _aeaf {_bbfdg .Set (_adg ,_gcef );};case *_ba .PdfObjectStreams :_gdgd (_bbfdg .Elements (),_ecc );case *_ba .PdfObjectStream :_dfc :=[]_ba .PdfObject {_bbfdg .PdfObjectDictionary };_gdgd (_dfc ,_ecc );_bbfdg .PdfObjectDictionary =_dfc [0].(*_ba .PdfObjectDictionary );
   196  case *_ba .PdfObjectDictionary :_bdaa :=_bbfdg .Keys ();_ecf :=make ([]_ba .PdfObject ,len (_bdaa ));for _bgce ,_ccgd :=range _bdaa {_ecf [_bgce ]=_bbfdg .Get (_ccgd );};_gdgd (_ecf ,_ecc );for _ebecd ,_cfeb :=range _bdaa {_bbfdg .Set (_cfeb ,_ecf [_ebecd ]);
   197  };case *_ba .PdfIndirectObject :_defa :=[]_ba .PdfObject {_bbfdg .PdfObject };_gdgd (_defa ,_ecc );_bbfdg .PdfObject =_defa [0];};};};
   198  
   199  // CompressStreams compresses uncompressed streams.
   200  // It implements interface model.Optimizer.
   201  type CompressStreams struct{};func _gcdb (_gedaf _ba .PdfObject ,_ceff map[_ba .PdfObject ]struct{})error {if _eba ,_eae :=_gedaf .(*_ba .PdfIndirectObject );_eae {_ceff [_gedaf ]=struct{}{};_gafe :=_gcdb (_eba .PdfObject ,_ceff );if _gafe !=nil {return _gafe ;
   202  };return nil ;};if _egb ,_gagf :=_gedaf .(*_ba .PdfObjectStream );_gagf {_ceff [_egb ]=struct{}{};_agf :=_gcdb (_egb .PdfObjectDictionary ,_ceff );if _agf !=nil {return _agf ;};return nil ;};if _dbd ,_gfa :=_gedaf .(*_ba .PdfObjectDictionary );_gfa {for _ ,_bdge :=range _dbd .Keys (){_eefa :=_dbd .Get (_bdge );
   203  _ =_eefa ;if _cggd ,_bff :=_eefa .(*_ba .PdfObjectReference );_bff {_eefa =_cggd .Resolve ();_dbd .Set (_bdge ,_eefa );};if _bdge !="\u0050\u0061\u0072\u0065\u006e\u0074"{if _geg :=_gcdb (_eefa ,_ceff );_geg !=nil {return _geg ;};};};return nil ;};if _gdeb ,_bace :=_gedaf .(*_ba .PdfObjectArray );
   204  _bace {if _gdeb ==nil {return _e .New ("\u0061\u0072\u0072a\u0079\u0020\u0069\u0073\u0020\u006e\u0069\u006c");};for _ggfa ,_degg :=range _gdeb .Elements (){if _ebc ,_bbc :=_degg .(*_ba .PdfObjectReference );_bbc {_degg =_ebc .Resolve ();_gdeb .Set (_ggfa ,_degg );
   205  };if _gfbf :=_gcdb (_degg ,_ceff );_gfbf !=nil {return _gfbf ;};};return nil ;};return nil ;};
   206  
   207  // GetOptimizers gets the list of optimizers in chain `c`.
   208  func (_bb *Chain )GetOptimizers ()[]_cff .Optimizer {return _bb ._fb };func _gbd (_dea *_cff .XObjectImage ,_ffg imageModifications )error {_deeg ,_gbgb :=_dea .ToImage ();if _gbgb !=nil {return _gbgb ;};if _ffg .Scale !=0{_deeg ,_gbgb =_fbdb (_deeg ,_ffg .Scale );
   209  if _gbgb !=nil {return _gbgb ;};};if _ffg .Encoding !=nil {_dea .Filter =_ffg .Encoding ;};_dea .Decode =nil ;switch _afgf :=_dea .Filter .(type ){case *_ba .FlateEncoder :if _afgf .Predictor !=1&&_afgf .Predictor !=11{_afgf .Predictor =1;};};if _gbgb =_dea .SetImage (_deeg ,nil );
   210  _gbgb !=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",_gbgb );return _gbgb ;};_dea .ToPdfObject ();return nil ;};
   211  
   212  // Append appends optimizers to the chain.
   213  func (_ef *Chain )Append (optimizers ..._cff .Optimizer ){_ef ._fb =append (_ef ._fb ,optimizers ...)};
   214  
   215  // Options describes PDF optimization parameters.
   216  type Options struct{CombineDuplicateStreams bool ;CombineDuplicateDirectObjects bool ;ImageUpperPPI float64 ;ImageQuality int ;UseObjectStreams bool ;CombineIdenticalIndirectObjects bool ;CompressStreams bool ;CleanFonts bool ;SubsetFonts bool ;CleanContentstream bool ;
   217  CleanUnusedResources bool ;};type content struct{_gab string ;_fga *_cff .PdfPageResources ;};
   218  
   219  // Optimize optimizes PDF objects to decrease PDF size.
   220  func (_fccf *ObjectStreams )Optimize (objects []_ba .PdfObject )(_gedb []_ba .PdfObject ,_cacea error ){_fegg :=&_ba .PdfObjectStreams {};_beca :=make ([]_ba .PdfObject ,0,len (objects ));for _ ,_aeba :=range objects {if _afc ,_efdb :=_aeba .(*_ba .PdfIndirectObject );
   221  _efdb &&_afc .GenerationNumber ==0{_fegg .Append (_aeba );}else {_beca =append (_beca ,_aeba );};};if _fegg .Len ()==0{return _beca ,nil ;};_gedb =make ([]_ba .PdfObject ,0,len (_beca )+_fegg .Len ()+1);if _fegg .Len ()> 1{_gedb =append (_gedb ,_fegg );
   222  };_gedb =append (_gedb ,_fegg .Elements ()...);_gedb =append (_gedb ,_beca ...);return _gedb ,nil ;};
   223  
   224  // Optimize optimizes PDF objects to decrease PDF size.
   225  func (_fccd *CombineDuplicateStreams )Optimize (objects []_ba .PdfObject )(_gcea []_ba .PdfObject ,_gcfa error ){_bbf :=make (map[_ba .PdfObject ]_ba .PdfObject );_cadg :=make (map[_ba .PdfObject ]struct{});_fged :=make (map[string ][]*_ba .PdfObjectStream );
   226  for _ ,_ffaa :=range objects {if _aee ,_agg :=_ffaa .(*_ba .PdfObjectStream );_agg {_cfbd :=_ce .New ();_cfbd .Write (_aee .Stream );_cfbd .Write ([]byte (_aee .PdfObjectDictionary .WriteString ()));_gabe :=string (_cfbd .Sum (nil ));_fged [_gabe ]=append (_fged [_gabe ],_aee );
   227  };};for _ ,_beaa :=range _fged {if len (_beaa )< 2{continue ;};_adaa :=_beaa [0];for _abg :=1;_abg < len (_beaa );_abg ++{_eaf :=_beaa [_abg ];_bbf [_eaf ]=_adaa ;_cadg [_eaf ]=struct{}{};};};_gcea =make ([]_ba .PdfObject ,0,len (objects )-len (_cadg ));
   228  for _ ,_aca :=range objects {if _ ,_bgcg :=_cadg [_aca ];_bgcg {continue ;};_gcea =append (_gcea ,_aca );};_gdgd (_gcea ,_bbf );return _gcea ,nil ;};
   229  
   230  // Optimize optimizes PDF objects to decrease PDF size.
   231  func (_fgae *Image )Optimize (objects []_ba .PdfObject )(_dcgb []_ba .PdfObject ,_dfgda error ){if _fgae .ImageQuality <=0{return objects ,nil ;};_fcge :=_ebaa (objects );if len (_fcge )==0{return objects ,nil ;};_edbf :=make (map[_ba .PdfObject ]_ba .PdfObject );
   232  _def :=make (map[_ba .PdfObject ]struct{});for _ ,_ebcc :=range _fcge {_abea :=_ebcc .Stream .Get ("\u0053\u004d\u0061s\u006b");_def [_abea ]=struct{}{};};for _ccgc ,_ebd :=range _fcge {_adeb :=_ebd .Stream ;if _ ,_faaf :=_def [_adeb ];_faaf {continue ;
   233  };_ebfa ,_bafe :=_cff .NewXObjectImageFromStream (_adeb );if _bafe !=nil {_f .Log .Debug ("\u0045\u0052\u0052\u004f\u0052\u003a\u0020\u0025\u002b\u0076",_bafe );continue ;};switch _ebfa .Filter .(type ){case *_ba .JBIG2Encoder :continue ;case *_ba .CCITTFaxEncoder :continue ;
   234  };_afd ,_bafe :=_ebfa .ToImage ();if _bafe !=nil {_f .Log .Debug ("\u0045\u0052\u0052\u004f\u0052\u003a\u0020\u0025\u002b\u0076",_bafe );continue ;};_cace :=_ba .NewDCTEncoder ();_cace .ColorComponents =_afd .ColorComponents ;_cace .Quality =_fgae .ImageQuality ;
   235  _cace .BitsPerComponent =_ebd .BitsPerComponent ;_cace .Width =_ebd .Width ;_cace .Height =_ebd .Height ;_cfed ,_bafe :=_cace .EncodeBytes (_afd .Data );if _bafe !=nil {_f .Log .Debug ("\u0045\u0052\u0052\u004f\u0052\u003a\u0020\u0025\u002b\u0076",_bafe );
   236  continue ;};var _ccgb _ba .StreamEncoder ;_ccgb =_cace ;{_bcbg :=_ba .NewFlateEncoder ();_fcgf :=_ba .NewMultiEncoder ();_fcgf .AddEncoder (_bcbg );_fcgf .AddEncoder (_cace );_caed ,_bbfd :=_fcgf .EncodeBytes (_afd .Data );if _bbfd !=nil {_f .Log .Debug ("\u0045\u0052\u0052\u004f\u0052\u003a\u0020\u0025\u002b\u0076",_bbfd );
   237  continue ;};if len (_caed )< len (_cfed ){_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 (_cfed ),len (_caed ),len (_adeb .Stream ));
   238  _cfed =_caed ;_ccgb =_fcgf ;};};_eecg :=len (_adeb .Stream );if _eecg < len (_cfed ){continue ;};_ebff :=&_ba .PdfObjectStream {Stream :_cfed };_ebff .PdfObjectReference =_adeb .PdfObjectReference ;_ebff .PdfObjectDictionary =_ba .MakeDict ();_ebff .Merge (_adeb .PdfObjectDictionary );
   239  _ebff .Merge (_ccgb .MakeStreamDict ());_ebff .Set ("\u004c\u0065\u006e\u0067\u0074\u0068",_ba .MakeInteger (int64 (len (_cfed ))));_edbf [_adeb ]=_ebff ;_fcge [_ccgc ].Stream =_ebff ;};_dcgb =make ([]_ba .PdfObject ,len (objects ));copy (_dcgb ,objects );
   240  _gdgd (_dcgb ,_edbf );return _dcgb ,nil ;};