unipdf/model/optimize/optimize.go
2023-07-28 12:14:31 +00:00

240 lines
43 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 (_ad "bytes";_b "crypto/md5";_de "errors";_d "fmt";_e "github.com/unidoc/unipdf/v3/common";_a "github.com/unidoc/unipdf/v3/contentstream";_be "github.com/unidoc/unipdf/v3/core";_cb "github.com/unidoc/unipdf/v3/extractor";_g "github.com/unidoc/unipdf/v3/internal/imageutil";
_fa "github.com/unidoc/unipdf/v3/internal/textencoding";_ea "github.com/unidoc/unipdf/v3/model";_cf "github.com/unidoc/unitype";_c "golang.org/x/image/draw";_ff "math";_cc "strings";);func _cacc (_eedg []_be .PdfObject )objectStructure {_gbb :=objectStructure {};
_acfc :=false ;for _ ,_aggc :=range _eedg {switch _agcbg :=_aggc .(type ){case *_be .PdfIndirectObject :_aece ,_cad :=_be .GetDict (_agcbg );if !_cad {continue ;};_aecg ,_cad :=_be .GetName (_aece .Get ("\u0054\u0079\u0070\u0065"));if !_cad {continue ;
};switch _aecg .String (){case "\u0043a\u0074\u0061\u006c\u006f\u0067":_gbb ._cagf =_aece ;_acfc =true ;};};if _acfc {break ;};};if !_acfc {return _gbb ;};_eagb ,_fab :=_be .GetDict (_gbb ._cagf .Get ("\u0050\u0061\u0067e\u0073"));if !_fab {return _gbb ;
};_gbb ._aadb =_eagb ;_ebga ,_fab :=_be .GetArray (_eagb .Get ("\u004b\u0069\u0064\u0073"));if !_fab {return _gbb ;};for _ ,_ggfa :=range _ebga .Elements (){_cgc ,_fcaf :=_be .GetIndirect (_ggfa );if !_fcaf {break ;};_gbb ._gggb =append (_gbb ._gggb ,_cgc );
};return _gbb ;};
// Append appends optimizers to the chain.
func (_gd *Chain )Append (optimizers ..._ea .Optimizer ){_gd ._bd =append (_gd ._bd ,optimizers ...)};func _eage (_fdb []_be .PdfObject ){for _ffb ,_cafd :=range _fdb {switch _eadg :=_cafd .(type ){case *_be .PdfIndirectObject :_eadg .ObjectNumber =int64 (_ffb +1);
_eadg .GenerationNumber =0;case *_be .PdfObjectStream :_eadg .ObjectNumber =int64 (_ffb +1);_eadg .GenerationNumber =0;case *_be .PdfObjectStreams :_eadg .ObjectNumber =int64 (_ffb +1);_eadg .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 ;};func _ffde (_efcf string ,_cca []string )bool {for _ ,_bdc :=range _cca {if _efcf ==_bdc {return true ;};};return false ;};
// Optimize optimizes PDF objects to decrease PDF size.
func (_baf *CompressStreams )Optimize (objects []_be .PdfObject )(_eag []_be .PdfObject ,_ffee error ){_eag =make ([]_be .PdfObject ,len (objects ));copy (_eag ,objects );for _ ,_dbcd :=range objects {_dcfc ,_ffg :=_be .GetStream (_dbcd );if !_ffg {continue ;
};if _adeb :=_dcfc .Get ("\u0046\u0069\u006c\u0074\u0065\u0072");_adeb !=nil {if _ ,_bcb :=_be .GetName (_adeb );_bcb {continue ;};if _dgf ,_ccc :=_be .GetArray (_adeb );_ccc &&_dgf .Len ()> 0{continue ;};};_aabd :=_be .NewFlateEncoder ();var _fbae []byte ;
_fbae ,_ffee =_aabd .EncodeBytes (_dcfc .Stream );if _ffee !=nil {return _eag ,_ffee ;};_bdgc :=_aabd .MakeStreamDict ();if len (_fbae )+len (_bdgc .WriteString ())< len (_dcfc .Stream ){_dcfc .Stream =_fbae ;_dcfc .PdfObjectDictionary .Merge (_bdgc );
_dcfc .PdfObjectDictionary .Set ("\u004c\u0065\u006e\u0067\u0074\u0068",_be .MakeInteger (int64 (len (_dcfc .Stream ))));};};return _eag ,nil ;};func _bde (_fg _be .PdfObject )[]content {if _fg ==nil {return nil ;};_aeg ,_abd :=_be .GetArray (_fg );if !_abd {_e .Log .Debug ("\u0041\u006e\u006e\u006fts\u0020\u006e\u006f\u0074\u0020\u0061\u006e\u0020\u0061\u0072\u0072\u0061\u0079");
return nil ;};var _eba []content ;for _ ,_aga :=range _aeg .Elements (){_df ,_cdgc :=_be .GetDict (_aga );if !_cdgc {_e .Log .Debug ("I\u0067\u006e\u006f\u0072\u0069\u006eg\u0020\u006e\u006f\u006e\u002d\u0064i\u0063\u0074\u0020\u0065\u006c\u0065\u006de\u006e\u0074\u0020\u0069\u006e\u0020\u0041\u006e\u006e\u006ft\u0073");
continue ;};_bea ,_cdgc :=_be .GetDict (_df .Get ("\u0041\u0050"));if !_cdgc {_e .Log .Debug ("\u004e\u006f\u0020\u0041P \u0065\u006e\u0074\u0072\u0079\u0020\u002d\u0020\u0073\u006b\u0069\u0070\u0070\u0069n\u0067");continue ;};_aea :=_be .TraceToDirectObject (_bea .Get ("\u004e"));
if _aea ==nil {_e .Log .Debug ("N\u006f\u0020\u004e\u0020en\u0074r\u0079\u0020\u002d\u0020\u0073k\u0069\u0070\u0070\u0069\u006e\u0067");continue ;};var _faf *_be .PdfObjectStream ;switch _ecd :=_aea .(type ){case *_be .PdfObjectDictionary :_affa ,_gge :=_be .GetName (_df .Get ("\u0041\u0053"));
if !_gge {_e .Log .Debug ("\u004e\u006f\u0020\u0041S \u0065\u006e\u0074\u0072\u0079\u0020\u002d\u0020\u0073\u006b\u0069\u0070\u0070\u0069n\u0067");continue ;};_faf ,_gge =_be .GetStream (_ecd .Get (*_affa ));if !_gge {_e .Log .Debug ("\u0046o\u0072\u006d\u0020\u006eo\u0074\u0020\u0066\u006f\u0075n\u0064 \u002d \u0073\u006b\u0069\u0070\u0070\u0069\u006eg");
continue ;};case *_be .PdfObjectStream :_faf =_ecd ;};if _faf ==nil {_e .Log .Debug ("\u0046\u006f\u0072m\u0020\u006e\u006f\u0074 \u0066\u006f\u0075\u006e\u0064\u0020\u0028n\u0069\u006c\u0029\u0020\u002d\u0020\u0073\u006b\u0069\u0070\u0070\u0069\u006e\u0067");
continue ;};_dadb ,_ccd :=_ea .NewXObjectFormFromStream (_faf );if _ccd !=nil {_e .Log .Debug ("\u0045\u0072\u0072\u006f\u0072\u0020l\u006f\u0061\u0064\u0069\u006e\u0067\u0020\u0066\u006f\u0072\u006d\u003a\u0020%\u0076\u0020\u002d\u0020\u0069\u0067\u006eo\u0072\u0069\u006e\u0067",_ccd );
continue ;};_gebb ,_ccd :=_dadb .GetContentStream ();if _ccd !=nil {_e .Log .Debug ("E\u0072\u0072\u006f\u0072\u0020\u0064e\u0063\u006f\u0064\u0069\u006e\u0067\u0020\u0063\u006fn\u0074\u0065\u006et\u0073:\u0020\u0025\u0076",_ccd );continue ;};_eba =append (_eba ,content {_dee :string (_gebb ),_aaf :_dadb .Resources });
};return _eba ;};func _abdf (_aabc _be .PdfObject )(string ,error ){_ggdg :=_be .TraceToDirectObject (_aabc );switch _deeb :=_ggdg .(type ){case *_be .PdfObjectString :return _deeb .Str (),nil ;case *_be .PdfObjectStream :_bfa ,_bad :=_be .DecodeStream (_deeb );
if _bad !=nil {return "",_bad ;};return string (_bfa ),nil ;};return "",_d .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",_ggdg );
};func _gbef (_edf []_be .PdfObject )[]*imageInfo {_aabg :=_be .PdfObjectName ("\u0053u\u0062\u0074\u0079\u0070\u0065");_bfae :=make (map[*_be .PdfObjectStream ]struct{});var _aaea []*imageInfo ;for _ ,_ffdbg :=range _edf {_bcbe ,_fcc :=_be .GetStream (_ffdbg );
if !_fcc {continue ;};if _ ,_dcea :=_bfae [_bcbe ];_dcea {continue ;};_bfae [_bcbe ]=struct{}{};_eeab :=_bcbe .PdfObjectDictionary .Get (_aabg );_fbad ,_fcc :=_be .GetName (_eeab );if !_fcc ||string (*_fbad )!="\u0049\u006d\u0061g\u0065"{continue ;};_adbb :=&imageInfo {Stream :_bcbe ,BitsPerComponent :8};
if _aad ,_gbf :=_be .GetIntVal (_bcbe .Get ("\u0042\u0069t\u0073\u0050\u0065r\u0043\u006f\u006d\u0070\u006f\u006e\u0065\u006e\u0074"));_gbf {_adbb .BitsPerComponent =_aad ;};if _abg ,_gccb :=_be .GetIntVal (_bcbe .Get ("\u0057\u0069\u0064t\u0068"));_gccb {_adbb .Width =_abg ;
};if _dfbe ,_bddd :=_be .GetIntVal (_bcbe .Get ("\u0048\u0065\u0069\u0067\u0068\u0074"));_bddd {_adbb .Height =_dfbe ;};_cga ,_dgc :=_ea .NewPdfColorspaceFromPdfObject (_bcbe .Get ("\u0043\u006f\u006c\u006f\u0072\u0053\u0070\u0061\u0063\u0065"));if _dgc !=nil {_e .Log .Debug ("\u0045R\u0052\u004f\u0052\u003a\u0020\u0025v",_dgc );
continue ;};if _cga ==nil {_bbec ,_befe :=_be .GetName (_bcbe .Get ("\u0046\u0069\u006c\u0074\u0065\u0072"));if _befe {switch _bbec .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":_cga =_ea .NewPdfColorspaceDeviceGray ();
_adbb .BitsPerComponent =1;};};};switch _cef :=_cga .(type ){case *_ea .PdfColorspaceDeviceRGB :_adbb .ColorComponents =3;case *_ea .PdfColorspaceDeviceGray :_adbb .ColorComponents =1;default:_e .Log .Debug ("\u004f\u0070\u0074\u0069\u006d\u0069\u007aa\u0074\u0069\u006fn\u0020\u0069\u0073 \u006e\u006ft\u0020\u0073\u0075\u0070\u0070\u006fr\u0074ed\u0020\u0066\u006f\u0072\u0020\u0063\u006f\u006c\u006f\u0072\u0020\u0073\u0070\u0061\u0063\u0065\u0020\u0025\u0054\u0020\u002d\u0020\u0073\u006b\u0069\u0070",_cef );
continue ;};_aaea =append (_aaea ,_adbb );};return _aaea ;};
// CombineDuplicateStreams combines duplicated streams by its data hash.
// It implements interface model.Optimizer.
type CombineDuplicateStreams struct{};
// CompressStreams compresses uncompressed streams.
// It implements interface model.Optimizer.
type CompressStreams struct{};func _bef (_fad *_be .PdfObjectStream ,_bf []rune ,_ede []_cf .GlyphIndex )error {_fad ,_ada :=_be .GetStream (_fad );if !_ada {_e .Log .Debug ("\u0045\u006d\u0062\u0065\u0064\u0064\u0065\u0064\u0020\u0066\u006f\u006e\u0074\u0020\u006f\u0062\u006a\u0065c\u0074\u0020\u006e\u006f\u0074\u0020\u0066o\u0075\u006e\u0064\u0020\u002d\u002d\u0020\u0041\u0042\u004f\u0052T\u0020\u0073\u0075\u0062\u0073\u0065\u0074\u0074\u0069\u006e\u0067");
return _de .New ("\u0066\u006f\u006e\u0074fi\u006c\u0065\u0032\u0020\u006e\u006f\u0074\u0020\u0066\u006f\u0075\u006e\u0064");};_aag ,_edc :=_be .DecodeStream (_fad );if _edc !=nil {_e .Log .Debug ("\u0044\u0065c\u006f\u0064\u0065 \u0065\u0072\u0072\u006f\u0072\u003a\u0020\u0025\u0076",_edc );
return _edc ;};_beec ,_edc :=_cf .Parse (_ad .NewReader (_aag ));if _edc !=nil {_e .Log .Debug ("\u0045\u0072\u0072\u006f\u0072\u0020\u0070\u0061\u0072\u0073\u0069n\u0067\u0020\u0025\u0064\u0020\u0062\u0079\u0074\u0065\u0020f\u006f\u006e\u0074",len (_fad .Stream ));
return _edc ;};_ege :=_ede ;if len (_bf )> 0{_fca :=_beec .LookupRunes (_bf );_ege =append (_ege ,_fca ...);};_beec ,_edc =_beec .SubsetKeepIndices (_ege );if _edc !=nil {_e .Log .Debug ("\u0045R\u0052\u004f\u0052\u0020s\u0075\u0062\u0073\u0065\u0074t\u0069n\u0067 \u0066\u006f\u006e\u0074\u003a\u0020\u0025v",_edc );
return _edc ;};var _gdff _ad .Buffer ;_edc =_beec .Write (&_gdff );if _edc !=nil {_e .Log .Debug ("\u0045\u0052\u0052\u004fR \u0057\u0072\u0069\u0074\u0069\u006e\u0067\u0020\u0066\u006f\u006e\u0074\u003a\u0020%\u0076",_edc );return _edc ;};if _gdff .Len ()> len (_aag ){_e .Log .Debug ("\u0052\u0065-\u0077\u0072\u0069\u0074\u0074\u0065\u006e\u0020\u0066\u006f\u006e\u0074\u0020\u0069\u0073\u0020\u006c\u0061\u0072\u0067\u0065\u0072\u0020\u0074\u0068\u0061\u006e\u0020\u006f\u0072\u0069\u0067\u0069\u006e\u0061\u006c\u0020\u002d\u0020\u0073\u006b\u0069\u0070");
return nil ;};_fced ,_edc :=_be .MakeStream (_gdff .Bytes (),_be .NewFlateEncoder ());if _edc !=nil {_e .Log .Debug ("\u0045\u0052\u0052\u004fR \u0057\u0072\u0069\u0074\u0069\u006e\u0067\u0020\u0066\u006f\u006e\u0074\u003a\u0020%\u0076",_edc );return _edc ;
};*_fad =*_fced ;_fad .Set ("\u004ce\u006e\u0067\u0074\u0068\u0031",_be .MakeInteger (int64 (_gdff .Len ())));return nil ;};func _afcd (_agab *_be .PdfObjectDictionary )[]string {_dddb :=[]string {};for _ ,_eff :=range _agab .Keys (){_dddb =append (_dddb ,_eff .String ());
};return _dddb ;};
// CleanUnusedResources represents an optimizer used to clean unused resources.
type CleanUnusedResources struct{};func _egd (_ecdb []_be .PdfObject )(map[_be .PdfObject ]struct{},error ){_egf :=_cacc (_ecdb );_bba :=_egf ._gggb ;_abc :=make (map[_be .PdfObject ]struct{});_ccdb :=_agd (_bba );for _ ,_dfb :=range _bba {_dgaa ,_abfb :=_be .GetDict (_dfb .PdfObject );
if !_abfb {continue ;};_ged ,_abfb :=_be .GetDict (_dgaa .Get ("\u0052e\u0073\u006f\u0075\u0072\u0063\u0065s"));if !_abfb {continue ;};_gfd :=_ccdb ["\u0058O\u0062\u006a\u0065\u0063\u0074"];_cgd ,_abfb :=_be .GetDict (_ged .Get ("\u0058O\u0062\u006a\u0065\u0063\u0074"));
if _abfb {_bfe :=_afcd (_cgd );for _ ,_ggbe :=range _bfe {if _ffde (_ggbe ,_gfd ){continue ;};_dabb :=*_be .MakeName (_ggbe );_cbga :=_cgd .Get (_dabb );_abc [_cbga ]=struct{}{};_cgd .Remove (_dabb );_gcc :=_efbd (_cbga ,_abc );if _gcc !=nil {_e .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",_cbga );
};};};_fcedc ,_abfb :=_be .GetDict (_ged .Get ("\u0046\u006f\u006e\u0074"));_cbf :=_ccdb ["\u0046\u006f\u006e\u0074"];if _abfb {_bge :=_afcd (_fcedc );for _ ,_eeda :=range _bge {if _ffde (_eeda ,_cbf ){continue ;};_fdg :=*_be .MakeName (_eeda );_bcg :=_fcedc .Get (_fdg );
_abc [_bcg ]=struct{}{};_fcedc .Remove (_fdg );_dfg :=_efbd (_bcg ,_abc );if _dfg !=nil {_e .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",_bcg );
};};};_fba ,_abfb :=_be .GetDict (_ged .Get ("\u0045x\u0074\u0047\u0053\u0074\u0061\u0074e"));if _abfb {_dfe :=_afcd (_fba );_ceb :=_ccdb ["\u0045x\u0074\u0047\u0053\u0074\u0061\u0074e"];for _ ,_fcf :=range _dfe {if _ffde (_fcf ,_ceb ){continue ;};_dgg :=*_be .MakeName (_fcf );
_gb :=_fba .Get (_dgg );_abc [_gb ]=struct{}{};_fba .Remove (_dgg );_ebbb :=_efbd (_gb ,_abc );if _ebbb !=nil {_e .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",_gb );
};};};};return _abc ,nil ;};func _bbaa (_aba *_ea .Image ,_dda float64 )(*_ea .Image ,error ){_dcff ,_dgd :=_aba .ToGoImage ();if _dgd !=nil {return nil ,_dgd ;};var _bae _g .Image ;_cdb ,_dfdd :=_dcff .(*_g .Monochrome );if _dfdd {if _dgd =_cdb .ResolveDecode ();
_dgd !=nil {return nil ,_dgd ;};_bae ,_dgd =_cdb .Scale (_dda );if _dgd !=nil {return nil ,_dgd ;};}else {_cag :=int (_ff .RoundToEven (float64 (_aba .Width )*_dda ));_bgeb :=int (_ff .RoundToEven (float64 (_aba .Height )*_dda ));_bae ,_dgd =_g .NewImage (_cag ,_bgeb ,int (_aba .BitsPerComponent ),_aba .ColorComponents ,nil ,nil ,nil );
if _dgd !=nil {return nil ,_dgd ;};_c .CatmullRom .Scale (_bae ,_bae .Bounds (),_dcff ,_dcff .Bounds (),_c .Over ,&_c .Options {});};_afa :=_bae .Base ();_fcfa :=&_ea .Image {Width :int64 (_afa .Width ),Height :int64 (_afa .Height ),BitsPerComponent :int64 (_afa .BitsPerComponent ),ColorComponents :_afa .ColorComponents ,Data :_afa .Data };
_fcfa .SetDecode (_afa .Decode );_fcfa .SetAlpha (_afa .Alpha );return _fcfa ,nil ;};
// ObjectStreams groups PDF objects to object streams.
// It implements interface model.Optimizer.
type ObjectStreams struct{};
// Optimize optimizes PDF objects to decrease PDF size.
func (_cge *CleanFonts )Optimize (objects []_be .PdfObject )(_cac []_be .PdfObject ,_bdg error ){var _edg map[*_be .PdfObjectStream ]struct{};if _cge .Subset {var _eca error ;_edg ,_eca =_ccf (objects );if _eca !=nil {_e .Log .Debug ("\u0045\u0052\u0052\u004fR\u003a\u0020\u0046\u0061\u0069\u006c\u0065\u0064\u0020\u0073u\u0062s\u0065\u0074\u0074\u0069\u006e\u0067\u003a \u0025\u0076",_eca );
return nil ,_eca ;};};for _ ,_gdb :=range objects {_gf ,_dbc :=_be .GetStream (_gdb );if !_dbc {continue ;};if _ ,_bgd :=_edg [_gf ];_bgd {continue ;};_dcb ,_ecb :=_be .NewEncoderFromStream (_gf );if _ecb !=nil {_e .Log .Debug ("\u0045\u0052RO\u0052\u0020\u0067e\u0074\u0074\u0069\u006eg e\u006eco\u0064\u0065\u0072\u003a\u0020\u0025\u0076 -\u0020\u0069\u0067\u006e\u006f\u0072\u0069n\u0067",_ecb );
continue ;};_gcf ,_ecb :=_dcb .DecodeStream (_gf );if _ecb !=nil {_e .Log .Debug ("\u0044\u0065\u0063\u006f\u0064\u0069\u006e\u0067\u0020\u0065r\u0072\u006f\u0072\u0020\u003a\u0020\u0025v\u0020\u002d\u0020\u0069\u0067\u006e\u006f\u0072\u0069\u006e\u0067",_ecb );
continue ;};if len (_gcf )< 4{continue ;};_dab :=string (_gcf [:4]);if _dab =="\u004f\u0054\u0054\u004f"{continue ;};if _dab !="\u0000\u0001\u0000\u0000"&&_dab !="\u0074\u0072\u0075\u0065"{continue ;};_cdg ,_ecb :=_cf .Parse (_ad .NewReader (_gcf ));if _ecb !=nil {_e .Log .Debug ("\u0045\u0052\u0052\u004f\u0052\u0020P\u0061\u0072\u0073\u0069\u006e\u0067\u0020\u0066\u006f\u006e\u0074\u003a\u0020%\u0076\u0020\u002d\u0020\u0069\u0067\u006eo\u0072\u0069\u006e\u0067",_ecb );
continue ;};_ecb =_cdg .Optimize ();if _ecb !=nil {_e .Log .Debug ("\u0045\u0052RO\u0052\u0020\u004fp\u0074\u0069\u006d\u0069zin\u0067 f\u006f\u006e\u0074\u003a\u0020\u0025\u0076 -\u0020\u0073\u006b\u0069\u0070\u0070\u0069n\u0067",_ecb );continue ;};var _fdc _ad .Buffer ;
_ecb =_cdg .Write (&_fdc );if _ecb !=nil {_e .Log .Debug ("\u0045\u0052\u0052\u004f\u0052\u0020W\u0072\u0069\u0074\u0069\u006e\u0067\u0020\u0066\u006f\u006e\u0074\u003a\u0020%\u0076\u0020\u002d\u0020\u0069\u0067\u006eo\u0072\u0069\u006e\u0067",_ecb );continue ;
};if _fdc .Len ()> len (_gcf ){_e .Log .Debug ("\u0052\u0065-\u0077\u0072\u0069\u0074\u0074\u0065\u006e\u0020\u0066\u006f\u006e\u0074\u0020\u0069\u0073\u0020\u006c\u0061\u0072\u0067\u0065\u0072\u0020\u0074\u0068\u0061\u006e\u0020\u006f\u0072\u0069\u0067\u0069\u006e\u0061\u006c\u0020\u002d\u0020\u0073\u006b\u0069\u0070");
continue ;};_cbb ,_ecb :=_be .MakeStream (_fdc .Bytes (),_be .NewFlateEncoder ());if _ecb !=nil {continue ;};*_gf =*_cbb ;_gf .Set ("\u004ce\u006e\u0067\u0074\u0068\u0031",_be .MakeInteger (int64 (_fdc .Len ())));};return objects ,nil ;};
// GetOptimizers gets the list of optimizers in chain `c`.
func (_cbg *Chain )GetOptimizers ()[]_ea .Optimizer {return _cbg ._bd };func _bg (_eb *_a .ContentStreamOperations )*_a .ContentStreamOperations {if _eb ==nil {return nil ;};_dac :=_a .ContentStreamOperations {};for _ ,_beg :=range *_eb {switch _beg .Operand {case "\u0042\u0044\u0043","\u0042\u004d\u0043","\u0045\u004d\u0043":continue ;
case "\u0054\u006d":if len (_beg .Params )==6{if _ag ,_dad :=_be .GetNumbersAsFloat (_beg .Params );_dad ==nil {if _ag [0]==1&&_ag [1]==0&&_ag [2]==0&&_ag [3]==1{_beg =&_a .ContentStreamOperation {Params :[]_be .PdfObject {_beg .Params [4],_beg .Params [5]},Operand :"\u0054\u0064"};
};};};};_dac =append (_dac ,_beg );};return &_dac ;};
// 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{};
// Optimize optimizes PDF objects to decrease PDF size.
func (_cage *ImagePPI )Optimize (objects []_be .PdfObject )(_dfbd []_be .PdfObject ,_ebg error ){if _cage .ImageUpperPPI <=0{return objects ,nil ;};_edb :=_gbef (objects );if len (_edb )==0{return objects ,nil ;};_fbce :=make (map[_be .PdfObject ]struct{});
for _ ,_eeec :=range _edb {_cbgd :=_eeec .Stream .PdfObjectDictionary .Get ("\u0053\u004d\u0061s\u006b");_fbce [_cbgd ]=struct{}{};};_bdcb :=make (map[*_be .PdfObjectStream ]*imageInfo );for _ ,_eeeg :=range _edb {_bdcb [_eeeg .Stream ]=_eeeg ;};var _afcc *_be .PdfObjectDictionary ;
for _ ,_dcafa :=range objects {if _aebd ,_bggg :=_be .GetDict (_dcafa );_afcc ==nil &&_bggg {if _gebe ,_cffa :=_be .GetName (_aebd .Get ("\u0054\u0079\u0070\u0065"));_cffa &&*_gebe =="\u0043a\u0074\u0061\u006c\u006f\u0067"{_afcc =_aebd ;};};};if _afcc ==nil {return objects ,nil ;
};_fgbd ,_edcc :=_be .GetDict (_afcc .Get ("\u0050\u0061\u0067e\u0073"));if !_edcc {return objects ,nil ;};_agbg ,_dgb :=_be .GetArray (_fgbd .Get ("\u004b\u0069\u0064\u0073"));if !_dgb {return objects ,nil ;};for _ ,_gca :=range _agbg .Elements (){_bgb :=make (map[string ]*imageInfo );
_gcb ,_dcbb :=_be .GetDict (_gca );if !_dcbb {continue ;};_afe ,_ :=_gaca (_gcb .Get ("\u0043\u006f\u006e\u0074\u0065\u006e\u0074\u0073"));if len (_afe )==0{continue ;};_bac ,_gedb :=_be .GetDict (_gcb .Get ("\u0052e\u0073\u006f\u0075\u0072\u0063\u0065s"));
if !_gedb {continue ;};_bgbc ,_ggbg :=_ea .NewPdfPageResourcesFromDict (_bac );if _ggbg !=nil {_e .Log .Debug ("\u0045\u0052\u0052\u004f\u0052\u0020\u0070\u0061\u0072\u0073\u0069\u006e\u0067\u0020\u0072\u0065\u0073\u006f\u0075\u0072\u0063\u0065\u0073\u0020-\u0020\u0069\u0067\u006e\u006fr\u0069\u006eg\u003a\u0020\u0025\u0076",_ggbg );
continue ;};_bcd ,_ggad :=_be .GetDict (_bac .Get ("\u0058O\u0062\u006a\u0065\u0063\u0074"));if !_ggad {continue ;};_gcbc :=_bcd .Keys ();for _ ,_cae :=range _gcbc {if _bedf ,_eeb :=_be .GetStream (_bcd .Get (_cae ));_eeb {if _eada ,_gaec :=_bdcb [_bedf ];
_gaec {_bgb [string (_cae )]=_eada ;};};};_decg :=_a .NewContentStreamParser (_afe );_ggf ,_ggbg :=_decg .Parse ();if _ggbg !=nil {_e .Log .Debug ("\u0045\u0052\u0052\u004f\u0052\u003a\u0020\u0025\u002b\u0076",_ggbg );continue ;};_gage :=_a .NewContentStreamProcessor (*_ggf );
_gage .AddHandler (_a .HandlerConditionEnumAllOperands ,"",func (_bbd *_a .ContentStreamOperation ,_fdf _a .GraphicsState ,_gdcf *_ea .PdfPageResources )error {switch _bbd .Operand {case "\u0044\u006f":if len (_bbd .Params )!=1{_e .Log .Debug ("E\u0052\u0052\u004f\u0052\u003a\u0020\u0049\u0067\u006e\u006f\u0072\u0069\u006e\u0067\u0020\u0044\u006f\u0020w\u0069\u0074\u0068\u0020\u006c\u0065\u006e\u0028\u0070\u0061ra\u006d\u0073\u0029 \u0021=\u0020\u0031");
return nil ;};_bafb ,_cafe :=_be .GetName (_bbd .Params [0]);if !_cafe {_e .Log .Debug ("\u0045\u0052\u0052O\u0052\u003a\u0020\u0049\u0067\u006e\u006f\u0072\u0069\u006e\u0067\u0020\u0044\u006f\u0020\u0077\u0069\u0074\u0068\u0020\u006e\u006f\u006e\u0020\u004e\u0061\u006d\u0065\u0020p\u0061\u0072\u0061\u006d\u0065\u0074\u0065\u0072");
return nil ;};if _face ,_gdfa :=_bgb [string (*_bafb )];_gdfa {_gdg :=_fdf .CTM .ScalingFactorX ();_fbde :=_fdf .CTM .ScalingFactorY ();_fceg ,_edbd :=_gdg /72.0,_fbde /72.0;_eaba ,_daab :=float64 (_face .Width )/_fceg ,float64 (_face .Height )/_edbd ;
if _fceg ==0||_edbd ==0{_eaba =72.0;_daab =72.0;};_face .PPI =_ff .Max (_face .PPI ,_eaba );_face .PPI =_ff .Max (_face .PPI ,_daab );};};return nil ;});_ggbg =_gage .Process (_bgbc );if _ggbg !=nil {_e .Log .Debug ("E\u0052\u0052\u004f\u0052 p\u0072o\u0063\u0065\u0073\u0073\u0069n\u0067\u003a\u0020\u0025\u002b\u0076",_ggbg );
continue ;};};for _ ,_bddgb :=range _edb {if _ ,_abdd :=_fbce [_bddgb .Stream ];_abdd {continue ;};if _bddgb .PPI <=_cage .ImageUpperPPI {continue ;};_cbe ,_bgbcf :=_ea .NewXObjectImageFromStream (_bddgb .Stream );if _bgbcf !=nil {_e .Log .Debug ("\u0045\u0052\u0052\u004f\u0052\u003a\u0020\u0025\u002b\u0076",_bgbcf );
continue ;};var _cgeg imageModifications ;_cgeg .Scale =_cage .ImageUpperPPI /_bddgb .PPI ;if _bddgb .BitsPerComponent ==1&&_bddgb .ColorComponents ==1{_fegb :=_ff .Round (_bddgb .PPI /_cage .ImageUpperPPI );_bccc :=_g .NextPowerOf2 (uint (_fegb ));if _g .InDelta (float64 (_bccc ),1/_cgeg .Scale ,0.3){_cgeg .Scale =float64 (1)/float64 (_bccc );
};if _ ,_eaf :=_cbe .Filter .(*_be .JBIG2Encoder );!_eaf {_cgeg .Encoding =_be .NewJBIG2Encoder ();};};if _bgbcf =_bdac (_cbe ,_cgeg );_bgbcf !=nil {_e .Log .Debug ("\u0045\u0072\u0072\u006f\u0072 \u0073\u0063\u0061\u006c\u0065\u0020\u0069\u006d\u0061\u0067\u0065\u0020\u006be\u0065\u0070\u0020\u006f\u0072\u0069\u0067\u0069\u006e\u0061\u006c\u0020\u0069\u006d\u0061\u0067\u0065\u003a\u0020\u0025\u0073",_bgbcf );
continue ;};_cgeg .Encoding =nil ;if _agadd ,_bga :=_be .GetStream (_bddgb .Stream .PdfObjectDictionary .Get ("\u0053\u004d\u0061s\u006b"));_bga {_bbf ,_accb :=_ea .NewXObjectImageFromStream (_agadd );if _accb !=nil {_e .Log .Debug ("\u0045\u0052\u0052\u004f\u0052\u003a\u0020\u0025\u002b\u0076",_accb );
continue ;};if _accb =_bdac (_bbf ,_cgeg );_accb !=nil {_e .Log .Debug ("\u0045\u0052\u0052\u004f\u0052\u003a\u0020\u0025\u002b\u0076",_accb );continue ;};};};return objects ,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 (_dd *CleanContentstream )Optimize (objects []_be .PdfObject )(_aa []_be .PdfObject ,_ab error ){_fb :=map[*_be .PdfObjectStream ]struct{}{};var _efa []*_be .PdfObjectStream ;_cbc :=func (_ddg *_be .PdfObjectStream ){if _ ,_aac :=_fb [_ddg ];!_aac {_fb [_ddg ]=struct{}{};
_efa =append (_efa ,_ddg );};};_abb :=map[_be .PdfObject ]bool {};_ae :=map[_be .PdfObject ]bool {};for _ ,_eg :=range objects {switch _ba :=_eg .(type ){case *_be .PdfIndirectObject :switch _ca :=_ba .PdfObject .(type ){case *_be .PdfObjectDictionary :if _bec ,_ge :=_be .GetName (_ca .Get ("\u0054\u0079\u0070\u0065"));
!_ge ||_bec .String ()!="\u0050\u0061\u0067\u0065"{continue ;};if _dg ,_aff :=_be .GetStream (_ca .Get ("\u0043\u006f\u006e\u0074\u0065\u006e\u0074\u0073"));_aff {_cbc (_dg );}else if _feg ,_ac :=_be .GetArray (_ca .Get ("\u0043\u006f\u006e\u0074\u0065\u006e\u0074\u0073"));
_ac {var _ecg []*_be .PdfObjectStream ;for _ ,_cdad :=range _feg .Elements (){if _bdf ,_bb :=_be .GetStream (_cdad );_bb {_ecg =append (_ecg ,_bdf );};};if len (_ecg )> 0{var _bbb _ad .Buffer ;for _ ,_ce :=range _ecg {if _cdag ,_efe :=_be .DecodeStream (_ce );
_efe ==nil {_bbb .Write (_cdag );};_abb [_ce ]=true ;};_ebb ,_eed :=_be .MakeStream (_bbb .Bytes (),_be .NewFlateEncoder ());if _eed !=nil {return nil ,_eed ;};_ae [_ebb ]=true ;_ca .Set ("\u0043\u006f\u006e\u0074\u0065\u006e\u0074\u0073",_ebb );_cbc (_ebb );
};};};case *_be .PdfObjectStream :if _agfd ,_eda :=_be .GetName (_ba .Get ("\u0054\u0079\u0070\u0065"));!_eda ||_agfd .String ()!="\u0058O\u0062\u006a\u0065\u0063\u0074"{continue ;};if _edd ,_ggg :=_be .GetName (_ba .Get ("\u0053u\u0062\u0074\u0079\u0070\u0065"));
!_ggg ||_edd .String ()!="\u0046\u006f\u0072\u006d"{continue ;};_cbc (_ba );};};for _ ,_fce :=range _efa {_ab =_gg (_fce );if _ab !=nil {return nil ,_ab ;};};_aa =nil ;for _ ,_aee :=range objects {if _abb [_aee ]{continue ;};_aa =append (_aa ,_aee );};
for _bed :=range _ae {_aa =append (_aa ,_bed );};return _aa ,nil ;};
// Optimize implements Optimizer interface.
func (_aebc *CleanUnusedResources )Optimize (objects []_be .PdfObject )(_deb []_be .PdfObject ,_ccdf error ){_aebf ,_ccdf :=_egd (objects );if _ccdf !=nil {return nil ,_ccdf ;};_ffe :=[]_be .PdfObject {};for _ ,_cdadd :=range objects {_ ,_age :=_aebf [_cdadd ];
if _age {continue ;};_ffe =append (_ffe ,_cdadd );};return _ffe ,nil ;};func _gaca (_eadf _be .PdfObject )(_eaa string ,_ddda []_be .PdfObject ){var _gbd _ad .Buffer ;switch _ecdfd :=_eadf .(type ){case *_be .PdfIndirectObject :_ddda =append (_ddda ,_ecdfd );
_eadf =_ecdfd .PdfObject ;};switch _afce :=_eadf .(type ){case *_be .PdfObjectStream :if _fge ,_bfaf :=_be .DecodeStream (_afce );_bfaf ==nil {_gbd .Write (_fge );_ddda =append (_ddda ,_afce );};case *_be .PdfObjectArray :for _ ,_fdbc :=range _afce .Elements (){switch _adca :=_fdbc .(type ){case *_be .PdfObjectStream :if _gfdd ,_fccf :=_be .DecodeStream (_adca );
_fccf ==nil {_gbd .Write (_gfdd );_ddda =append (_ddda ,_adca );};};};};return _gbd .String (),_ddda ;};
// New creates a optimizers chain from options.
func New (options Options )*Chain {_bdad :=new (Chain );if options .CleanFonts ||options .SubsetFonts {_bdad .Append (&CleanFonts {Subset :options .SubsetFonts });};if options .CleanContentstream {_bdad .Append (new (CleanContentstream ));};if options .ImageUpperPPI > 0{_ceg :=new (ImagePPI );
_ceg .ImageUpperPPI =options .ImageUpperPPI ;_bdad .Append (_ceg );};if options .ImageQuality > 0{_ebbc :=new (Image );_ebbc .ImageQuality =options .ImageQuality ;_bdad .Append (_ebbc );};if options .CombineDuplicateDirectObjects {_bdad .Append (new (CombineDuplicateDirectObjects ));
};if options .CombineDuplicateStreams {_bdad .Append (new (CombineDuplicateStreams ));};if options .CombineIdenticalIndirectObjects {_bdad .Append (new (CombineIdenticalIndirectObjects ));};if options .UseObjectStreams {_bdad .Append (new (ObjectStreams ));
};if options .CompressStreams {_bdad .Append (new (CompressStreams ));};if options .CleanUnusedResources {_bdad .Append (new (CleanUnusedResources ));};return _bdad ;};
// CombineIdenticalIndirectObjects combines identical indirect objects.
// It implements interface model.Optimizer.
type CombineIdenticalIndirectObjects struct{};type imageModifications struct{Scale float64 ;Encoding _be .StreamEncoder ;};func _ccf (_baaa []_be .PdfObject )(_fbc map[*_be .PdfObjectStream ]struct{},_egg error ){_fbc =map[*_be .PdfObjectStream ]struct{}{};
_bee :=map[*_ea .PdfFont ]struct{}{};_ebe :=_cacc (_baaa );for _ ,_acb :=range _ebe ._gggb {_gdf ,_fbf :=_be .GetDict (_acb .PdfObject );if !_fbf {continue ;};_ebc ,_fbf :=_be .GetDict (_gdf .Get ("\u0052e\u0073\u006f\u0075\u0072\u0063\u0065s"));if !_fbf {continue ;
};_afc ,_ :=_gaca (_gdf .Get ("\u0043\u006f\u006e\u0074\u0065\u006e\u0074\u0073"));_bdd ,_bcc :=_ea .NewPdfPageResourcesFromDict (_ebc );if _bcc !=nil {return nil ,_bcc ;};_efb :=[]content {{_dee :_afc ,_aaf :_bdd }};_gc :=_bde (_gdf .Get ("\u0041\u006e\u006e\u006f\u0074\u0073"));
if _gc !=nil {_efb =append (_efb ,_gc ...);};for _ ,_gag :=range _efb {_aeed ,_gdd :=_cb .NewFromContents (_gag ._dee ,_gag ._aaf );if _gdd !=nil {return nil ,_gdd ;};_fcb ,_ ,_ ,_gdd :=_aeed .ExtractPageText ();if _gdd !=nil {return nil ,_gdd ;};for _ ,_fbd :=range _fcb .Marks ().Elements (){if _fbd .Font ==nil {continue ;
};if _ ,_abf :=_bee [_fbd .Font ];!_abf {_bee [_fbd .Font ]=struct{}{};};};};};_bda :=map[*_be .PdfObjectStream ][]*_ea .PdfFont {};for _efag :=range _bee {_aaa :=_efag .FontDescriptor ();if _aaa ==nil ||_aaa .FontFile2 ==nil {continue ;};_dga ,_edag :=_be .GetStream (_aaa .FontFile2 );
if !_edag {continue ;};_bda [_dga ]=append (_bda [_dga ],_efag );};for _agg :=range _bda {var _dc []rune ;var _bgf []_cf .GlyphIndex ;for _ ,_cdd :=range _bda [_agg ]{switch _aec :=_cdd .Encoder ().(type ){case *_fa .IdentityEncoder :_begg :=_aec .RegisteredRunes ();
_beb :=make ([]_cf .GlyphIndex ,len (_begg ));for _fd ,_cee :=range _begg {_beb [_fd ]=_cf .GlyphIndex (_cee );};_bgf =append (_bgf ,_beb ...);case *_fa .TrueTypeFontEncoder :_caf :=_aec .RegisteredRunes ();_dc =append (_dc ,_caf ...);case _fa .SimpleEncoder :_aef :=_aec .Charcodes ();
for _ ,_ffdb :=range _aef {_dbf ,_becg :=_aec .CharcodeToRune (_ffdb );if !_becg {_e .Log .Debug ("\u0043\u0068a\u0072\u0063\u006f\u0064\u0065\u003c\u002d\u003e\u0072\u0075\u006e\u0065\u0020\u006e\u006f\u0074\u0020\u0066\u006f\u0075\u006e\u0064: \u0025\u0064",_ffdb );
continue ;};_dc =append (_dc ,_dbf );};};};_egg =_bef (_agg ,_dc ,_bgf );if _egg !=nil {_e .Log .Debug ("\u0045\u0052\u0052\u004f\u0052\u0020\u0073\u0075\u0062\u0073\u0065\u0074\u0074\u0069\u006eg\u0020f\u006f\u006e\u0074\u0020\u0073\u0074\u0072\u0065\u0061\u006d\u003a\u0020\u0025\u0076",_egg );
return nil ,_egg ;};_fbc [_agg ]=struct{}{};};return _fbc ,nil ;};
// Optimize optimizes PDF objects to decrease PDF size.
func (_fac *CombineDuplicateDirectObjects )Optimize (objects []_be .PdfObject )(_edgf []_be .PdfObject ,_gegb error ){_eage (objects );_ddc :=make (map[string ][]*_be .PdfObjectDictionary );var _dca func (_gagc *_be .PdfObjectDictionary );_dca =func (_fgfc *_be .PdfObjectDictionary ){for _ ,_gec :=range _fgfc .Keys (){_becf :=_fgfc .Get (_gec );
if _cce ,_fga :=_becf .(*_be .PdfObjectDictionary );_fga {_afb :=_b .New ();_afb .Write ([]byte (_cce .WriteString ()));_dcf :=string (_afb .Sum (nil ));_ddc [_dcf ]=append (_ddc [_dcf ],_cce );_dca (_cce );};};};for _ ,_bebg :=range objects {_eac ,_aggf :=_bebg .(*_be .PdfIndirectObject );
if !_aggf {continue ;};if _gdbb ,_baac :=_eac .PdfObject .(*_be .PdfObjectDictionary );_baac {_dca (_gdbb );};};_geec :=make ([]_be .PdfObject ,0,len (_ddc ));_gab :=make (map[_be .PdfObject ]_be .PdfObject );for _ ,_fee :=range _ddc {if len (_fee )< 2{continue ;
};_dce :=_be .MakeDict ();_dce .Merge (_fee [0]);_aaae :=_be .MakeIndirectObject (_dce );_geec =append (_geec ,_aaae );for _gabg :=0;_gabg < len (_fee );_gabg ++{_bbea :=_fee [_gabg ];_gab [_bbea ]=_aaae ;};};_edgf =make ([]_be .PdfObject ,len (objects ));
copy (_edgf ,objects );_edgf =append (_geec ,_edgf ...);_dgdf (_edgf ,_gab );return _edgf ,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 ;
CleanUnusedResources bool ;};func _dgdf (_ccdgf []_be .PdfObject ,_cgae map[_be .PdfObject ]_be .PdfObject ){if len (_cgae )==0{return ;};for _ffca ,_adg :=range _ccdgf {if _ddgg ,_feec :=_cgae [_adg ];_feec {_ccdgf [_ffca ]=_ddgg ;continue ;};_cgae [_adg ]=_adg ;
switch _cgf :=_adg .(type ){case *_be .PdfObjectArray :_edgb :=make ([]_be .PdfObject ,_cgf .Len ());copy (_edgb ,_cgf .Elements ());_dgdf (_edgb ,_cgae );for _gac ,_aeggg :=range _edgb {_cgf .Set (_gac ,_aeggg );};case *_be .PdfObjectStreams :_dgdf (_cgf .Elements (),_cgae );
case *_be .PdfObjectStream :_gagcd :=[]_be .PdfObject {_cgf .PdfObjectDictionary };_dgdf (_gagcd ,_cgae );_cgf .PdfObjectDictionary =_gagcd [0].(*_be .PdfObjectDictionary );case *_be .PdfObjectDictionary :_fbdg :=_cgf .Keys ();_gea :=make ([]_be .PdfObject ,len (_fbdg ));
for _fdd ,_ebfe :=range _fbdg {_gea [_fdd ]=_cgf .Get (_ebfe );};_dgdf (_gea ,_cgae );for _eceg ,_ggaea :=range _fbdg {_cgf .Set (_ggaea ,_gea [_eceg ]);};case *_be .PdfIndirectObject :_eef :=[]_be .PdfObject {_cgf .PdfObject };_dgdf (_eef ,_cgae );_cgf .PdfObject =_eef [0];
};};};
// Chain allows to use sequence of optimizers.
// It implements interface model.Optimizer.
type Chain struct{_bd []_ea .Optimizer };
// Optimize optimizes PDF objects to decrease PDF size.
func (_efcd *CombineDuplicateStreams )Optimize (objects []_be .PdfObject )(_ece []_be .PdfObject ,_efg error ){_fgag :=make (map[_be .PdfObject ]_be .PdfObject );_ddbb :=make (map[_be .PdfObject ]struct{});_fcbe :=make (map[string ][]*_be .PdfObjectStream );
for _ ,_agbe :=range objects {if _adc ,_bbce :=_agbe .(*_be .PdfObjectStream );_bbce {_adf :=_b .New ();_adf .Write (_adc .Stream );_adf .Write ([]byte (_adc .PdfObjectDictionary .WriteString ()));_cbcg :=string (_adf .Sum (nil ));_fcbe [_cbcg ]=append (_fcbe [_cbcg ],_adc );
};};for _ ,_dfd :=range _fcbe {if len (_dfd )< 2{continue ;};_egge :=_dfd [0];for _cff :=1;_cff < len (_dfd );_cff ++{_efgc :=_dfd [_cff ];_fgag [_efgc ]=_egge ;_ddbb [_efgc ]=struct{}{};};};_ece =make ([]_be .PdfObject ,0,len (objects )-len (_ddbb ));
for _ ,_fbdf :=range objects {if _ ,_bebf :=_ddbb [_fbdf ];_bebf {continue ;};_ece =append (_ece ,_fbdf );};_dgdf (_ece ,_fgag );return _ece ,nil ;};func _bdac (_fag *_ea .XObjectImage ,_dbfbb imageModifications )error {_fda ,_ccbg :=_fag .ToImage ();if _ccbg !=nil {return _ccbg ;
};if _dbfbb .Scale !=0{_fda ,_ccbg =_bbaa (_fda ,_dbfbb .Scale );if _ccbg !=nil {return _ccbg ;};};if _dbfbb .Encoding !=nil {_fag .Filter =_dbfbb .Encoding ;};_fag .Decode =nil ;switch _ggec :=_fag .Filter .(type ){case *_be .FlateEncoder :if _ggec .Predictor !=1&&_ggec .Predictor !=11{_ggec .Predictor =1;
};};if _ccbg =_fag .SetImage (_fda ,nil );_ccbg !=nil {_e .Log .Debug ("\u0045\u0072\u0072or\u0020\u0073\u0065\u0074\u0074\u0069\u006e\u0067\u0020\u0069\u006d\u0061\u0067\u0065\u003a\u0020\u0025\u0076",_ccbg );return _ccbg ;};_fag .ToPdfObject ();return nil ;
};
// Optimize optimizes PDF objects to decrease PDF size.
func (_aaead *ObjectStreams )Optimize (objects []_be .PdfObject )(_ggee []_be .PdfObject ,_gfe error ){_eagf :=&_be .PdfObjectStreams {};_acec :=make ([]_be .PdfObject ,0,len (objects ));for _ ,_efcb :=range objects {if _fed ,_cgb :=_efcb .(*_be .PdfIndirectObject );
_cgb &&_fed .GenerationNumber ==0{_eagf .Append (_efcb );}else {_acec =append (_acec ,_efcb );};};if _eagf .Len ()==0{return _acec ,nil ;};_ggee =make ([]_be .PdfObject ,0,len (_acec )+_eagf .Len ()+1);if _eagf .Len ()> 1{_ggee =append (_ggee ,_eagf );
};_ggee =append (_ggee ,_eagf .Elements ()...);_ggee =append (_ggee ,_acec ...);return _ggee ,nil ;};
// 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 (_ed *Chain )Optimize (objects []_be .PdfObject )(_da []_be .PdfObject ,_db error ){_bc :=objects ;for _ ,_cd :=range _ed ._bd {_ffd ,_eab :=_cd .Optimize (_bc );if _eab !=nil {_e .Log .Debug ("\u0045\u0052\u0052OR\u0020\u004f\u0070\u0074\u0069\u006d\u0069\u007a\u0061\u0074\u0069\u006f\u006e\u003a\u0020\u0025\u002b\u0076",_eab );
continue ;};_bc =_ffd ;};return _bc ,nil ;};
// Optimize optimizes PDF objects to decrease PDF size.
func (_ecca *CombineIdenticalIndirectObjects )Optimize (objects []_be .PdfObject )(_aceb []_be .PdfObject ,_gce error ){_eage (objects );_cfa :=make (map[_be .PdfObject ]_be .PdfObject );_gdde :=make (map[_be .PdfObject ]struct{});_gcd :=make (map[string ][]*_be .PdfIndirectObject );
for _ ,_ceee :=range objects {_bedc ,_edec :=_ceee .(*_be .PdfIndirectObject );if !_edec {continue ;};if _afd ,_gcfd :=_bedc .PdfObject .(*_be .PdfObjectDictionary );_gcfd {if _dbfb ,_bedd :=_afd .Get ("\u0054\u0079\u0070\u0065").(*_be .PdfObjectName );
_bedd &&*_dbfb =="\u0050\u0061\u0067\u0065"{continue ;};_dggf :=_b .New ();_dggf .Write ([]byte (_afd .WriteString ()));_gecc :=string (_dggf .Sum (nil ));_gcd [_gecc ]=append (_gcd [_gecc ],_bedc );};};for _ ,_feag :=range _gcd {if len (_feag )< 2{continue ;
};_bce :=_feag [0];for _fde :=1;_fde < len (_feag );_fde ++{_egac :=_feag [_fde ];_cfa [_egac ]=_bce ;_gdde [_egac ]=struct{}{};};};_aceb =make ([]_be .PdfObject ,0,len (objects )-len (_gdde ));for _ ,_bfd :=range objects {if _ ,_agad :=_gdde [_bfd ];_agad {continue ;
};_aceb =append (_aceb ,_bfd );};_dgdf (_aceb ,_cfa );return _aceb ,nil ;};
// Optimize optimizes PDF objects to decrease PDF size.
func (_gddg *Image )Optimize (objects []_be .PdfObject )(_fgb []_be .PdfObject ,_bddg error ){if _gddg .ImageQuality <=0{return objects ,nil ;};_ebbg :=_gbef (objects );if len (_ebbg )==0{return objects ,nil ;};_deec :=make (map[_be .PdfObject ]_be .PdfObject );
_cfb :=make (map[_be .PdfObject ]struct{});for _ ,_cbd :=range _ebbg {_fcg :=_cbd .Stream .Get ("\u0053\u004d\u0061s\u006b");_cfb [_fcg ]=struct{}{};};for _agbd ,_efd :=range _ebbg {_bbaf :=_efd .Stream ;if _ ,_efdf :=_cfb [_bbaf ];_efdf {continue ;};_gddf ,_geeg :=_ea .NewXObjectImageFromStream (_bbaf );
if _geeg !=nil {_e .Log .Debug ("\u0045\u0052\u0052\u004f\u0052\u003a\u0020\u0025\u002b\u0076",_geeg );continue ;};switch _gddf .Filter .(type ){case *_be .JBIG2Encoder :continue ;case *_be .CCITTFaxEncoder :continue ;};_ecdf ,_geeg :=_gddf .ToImage ();
if _geeg !=nil {_e .Log .Debug ("\u0045\u0052\u0052\u004f\u0052\u003a\u0020\u0025\u002b\u0076",_geeg );continue ;};_dabc :=_be .NewDCTEncoder ();_dabc .ColorComponents =_ecdf .ColorComponents ;_dabc .Quality =_gddg .ImageQuality ;_dabc .BitsPerComponent =_efd .BitsPerComponent ;
_dabc .Width =_efd .Width ;_dabc .Height =_efd .Height ;_dfgb ,_geeg :=_dabc .EncodeBytes (_ecdf .Data );if _geeg !=nil {_e .Log .Debug ("\u0045\u0052\u0052\u004f\u0052\u003a\u0020\u0025\u002b\u0076",_geeg );continue ;};var _beeca _be .StreamEncoder ;_beeca =_dabc ;
{_ccef :=_be .NewFlateEncoder ();_bca :=_be .NewMultiEncoder ();_bca .AddEncoder (_ccef );_bca .AddEncoder (_dabc );_efeag ,_dec :=_bca .EncodeBytes (_ecdf .Data );if _dec !=nil {_e .Log .Debug ("\u0045\u0052\u0052\u004f\u0052\u003a\u0020\u0025\u002b\u0076",_dec );
continue ;};if len (_efeag )< len (_dfgb ){_e .Log .Trace ("\u004d\u0075\u006c\u0074\u0069\u0020\u0065\u006e\u0063\u0020\u0069\u006d\u0070\u0072\u006f\u0076\u0065\u0073\u003a\u0020\u0025\u0064\u0020\u0074o\u0020\u0025\u0064\u0020\u0028o\u0072\u0069g\u0020\u0025\u0064\u0029",len (_dfgb ),len (_efeag ),len (_bbaf .Stream ));
_dfgb =_efeag ;_beeca =_bca ;};};_fdcc :=len (_bbaf .Stream );if _fdcc < len (_dfgb ){continue ;};_bege :=&_be .PdfObjectStream {Stream :_dfgb };_bege .PdfObjectReference =_bbaf .PdfObjectReference ;_bege .PdfObjectDictionary =_be .MakeDict ();_bege .Merge (_bbaf .PdfObjectDictionary );
_bege .Merge (_beeca .MakeStreamDict ());_bege .Set ("\u004c\u0065\u006e\u0067\u0074\u0068",_be .MakeInteger (int64 (len (_dfgb ))));_deec [_bbaf ]=_bege ;_ebbg [_agbd ].Stream =_bege ;};_fgb =make ([]_be .PdfObject ,len (objects ));copy (_fgb ,objects );
_dgdf (_fgb ,_deec );return _fgb ,nil ;};func _efbd (_agcg _be .PdfObject ,_bbgd map[_be .PdfObject ]struct{})error {if _acbf ,_bdaf :=_agcg .(*_be .PdfIndirectObject );_bdaf {_bbgd [_agcg ]=struct{}{};_agb :=_efbd (_acbf .PdfObject ,_bbgd );if _agb !=nil {return _agb ;
};return nil ;};if _cbgf ,_efef :=_agcg .(*_be .PdfObjectStream );_efef {_bbgd [_cbgf ]=struct{}{};_dbfc :=_efbd (_cbgf .PdfObjectDictionary ,_bbgd );if _dbfc !=nil {return _dbfc ;};return nil ;};if _ead ,_ffc :=_agcg .(*_be .PdfObjectDictionary );_ffc {for _ ,_dbd :=range _ead .Keys (){_ecab :=_ead .Get (_dbd );
_ =_ecab ;if _acfg ,_dggd :=_ecab .(*_be .PdfObjectReference );_dggd {_ecab =_acfg .Resolve ();_ead .Set (_dbd ,_ecab );};if _dbd !="\u0050\u0061\u0072\u0065\u006e\u0074"{if _dbg :=_efbd (_ecab ,_bbgd );_dbg !=nil {return _dbg ;};};};return nil ;};if _daag ,_bbe :=_agcg .(*_be .PdfObjectArray );
_bbe {if _daag ==nil {return _de .New ("\u0061\u0072\u0072a\u0079\u0020\u0069\u0073\u0020\u006e\u0069\u006c");};for _dgeg ,_aacf :=range _daag .Elements (){if _bgg ,_ggd :=_aacf .(*_be .PdfObjectReference );_ggd {_aacf =_bgg .Resolve ();_daag .Set (_dgeg ,_aacf );
};if _ecc :=_efbd (_aacf ,_bbgd );_ecc !=nil {return _ecc ;};};return nil ;};return 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 ;};func _gg (_cg *_be .PdfObjectStream )error {_ef ,_ee :=_be .DecodeStream (_cg );if _ee !=nil {return _ee ;};_eea :=_a .NewContentStreamParser (string (_ef ));_fe ,_ee :=_eea .Parse ();if _ee !=nil {return _ee ;};_fe =_bg (_fe );
_fc :=_fe .Bytes ();if len (_fc )>=len (_ef ){return nil ;};_agf ,_ee :=_be .MakeStream (_fe .Bytes (),_be .NewFlateEncoder ());if _ee !=nil {return _ee ;};_cg .Stream =_agf .Stream ;_cg .Merge (_agf .PdfObjectDictionary );return nil ;};func _agd (_ceef []*_be .PdfIndirectObject )map[string ][]string {_ded :=map[string ][]string {};
for _ ,_efc :=range _ceef {_aegg ,_fgf :=_be .GetDict (_efc .PdfObject );if !_fgf {continue ;};_bbg :=_aegg .Get ("\u0043\u006f\u006e\u0074\u0065\u006e\u0074\u0073");_daf :=_be .TraceToDirectObject (_bbg );var _ccdg []string ;if _ade ,_aae :=_daf .(*_be .PdfObjectArray );
_aae {for _ ,_dea :=range _ade .Elements (){_aab ,_daa :=_abdf (_dea );if _daa !=nil {continue ;};_ccdg =append (_ccdg ,_aab );};};_fea :=_cc .Join (_ccdg ,"\u0020");_debb :=_a .NewContentStreamParser (_fea );_bbcd ,_fafa :=_debb .Parse ();if _fafa !=nil {continue ;
};for _ ,_agge :=range *_bbcd {_gee :=_agge .Operand ;_edee :=_agge .Params ;switch _gee {case "\u0044\u006f":_acf :=_edee [0].String ();if _ ,_geg :=_ded ["\u0058O\u0062\u006a\u0065\u0063\u0074"];!_geg {_ded ["\u0058O\u0062\u006a\u0065\u0063\u0074"]=[]string {_acf };
}else {_ded ["\u0058O\u0062\u006a\u0065\u0063\u0074"]=append (_ded ["\u0058O\u0062\u006a\u0065\u0063\u0074"],_acf );};case "\u0054\u0066":_gad :=_edee [0].String ();if _ ,_agc :=_ded ["\u0046\u006f\u006e\u0074"];!_agc {_ded ["\u0046\u006f\u006e\u0074"]=[]string {_gad };
}else {_ded ["\u0046\u006f\u006e\u0074"]=append (_ded ["\u0046\u006f\u006e\u0074"],_gad );};case "\u0067\u0073":_aaac :=_edee [0].String ();if _ ,_fbe :=_ded ["\u0045x\u0074\u0047\u0053\u0074\u0061\u0074e"];!_fbe {_ded ["\u0045x\u0074\u0047\u0053\u0074\u0061\u0074e"]=[]string {_aaac };
}else {_ded ["\u0045x\u0074\u0047\u0053\u0074\u0061\u0074e"]=append (_ded ["\u0045x\u0074\u0047\u0053\u0074\u0061\u0074e"],_aaac );};};};};return _ded ;};type content struct{_dee string ;_aaf *_ea .PdfPageResources ;};type objectStructure struct{_cagf *_be .PdfObjectDictionary ;
_aadb *_be .PdfObjectDictionary ;_gggb []*_be .PdfIndirectObject ;};type imageInfo struct{BitsPerComponent int ;ColorComponents int ;Width int ;Height int ;Stream *_be .PdfObjectStream ;PPI float64 ;};