mirror of
https://github.com/unidoc/unipdf.git
synced 2025-04-27 13:48:51 +08:00
99 lines
35 KiB
Go
99 lines
35 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 (_cgf "bytes";_a "crypto/md5";_cc "errors";_e "github.com/unidoc/unipdf/v3/common";_cf "github.com/unidoc/unipdf/v3/contentstream";_fd "github.com/unidoc/unipdf/v3/core";_cg "github.com/unidoc/unipdf/v3/extractor";_aa "github.com/unidoc/unipdf/v3/internal/imageutil";_g "github.com/unidoc/unipdf/v3/internal/textencoding";_fe "github.com/unidoc/unipdf/v3/model";_gf "github.com/unidoc/unitype";_c "golang.org/x/image/draw";_ff "math";);
|
|
|
|
// Append appends optimizers to the chain.
|
|
func (_b *Chain )Append (optimizers ..._fe .Optimizer ){_b ._cgd =append (_b ._cgd ,optimizers ...)};
|
|
|
|
// Optimize optimizes PDF objects to decrease PDF size.
|
|
func (_cfbeb *ObjectStreams )Optimize (objects []_fd .PdfObject )(_bbcf []_fd .PdfObject ,_feb error ){_ccaa :=&_fd .PdfObjectStreams {};_bffa :=make ([]_fd .PdfObject ,0,len (objects ));for _ ,_ebb :=range objects {if _ggdg ,_ded :=_ebb .(*_fd .PdfIndirectObject );_ded &&_ggdg .GenerationNumber ==0{_ccaa .Append (_ebb );}else {_bffa =append (_bffa ,_ebb );};};if _ccaa .Len ()==0{return _bffa ,nil ;};_bbcf =make ([]_fd .PdfObject ,0,len (_bffa )+_ccaa .Len ()+1);if _ccaa .Len ()> 1{_bbcf =append (_bbcf ,_ccaa );};_bbcf =append (_bbcf ,_ccaa .Elements ()...);_bbcf =append (_bbcf ,_bffa ...);return _bbcf ,nil ;};
|
|
|
|
// Optimize optimizes PDF objects to decrease PDF size.
|
|
func (_bee *CombineIdenticalIndirectObjects )Optimize (objects []_fd .PdfObject )(_eaac []_fd .PdfObject ,_gbgc error ){_bcge (objects );_cgde :=make (map[_fd .PdfObject ]_fd .PdfObject );_dda :=make (map[_fd .PdfObject ]struct{});_fef :=make (map[string ][]*_fd .PdfIndirectObject );for _ ,_gdb :=range objects {_ebca ,_edab :=_gdb .(*_fd .PdfIndirectObject );if !_edab {continue ;};if _cdb ,_age :=_ebca .PdfObject .(*_fd .PdfObjectDictionary );_age {if _faed ,_dgc :=_cdb .Get ("\u0054\u0079\u0070\u0065").(*_fd .PdfObjectName );_dgc &&*_faed =="\u0050\u0061\u0067\u0065"{continue ;};_cebd :=_a .New ();_cebd .Write ([]byte (_cdb .WriteString ()));_dfc :=string (_cebd .Sum (nil ));_fef [_dfc ]=append (_fef [_dfc ],_ebca );};};for _ ,_cfd :=range _fef {if len (_cfd )< 2{continue ;};_dee :=_cfd [0];for _aadf :=1;_aadf < len (_cfd );_aadf ++{_gee :=_cfd [_aadf ];_cgde [_gee ]=_dee ;_dda [_gee ]=struct{}{};};};_eaac =make ([]_fd .PdfObject ,0,len (objects )-len (_dda ));for _ ,_acfe :=range objects {if _ ,_bgb :=_dda [_acfe ];_bgb {continue ;};_eaac =append (_eaac ,_acfe );};_fgaf (_eaac ,_cgde );return _eaac ,nil ;};type imageInfo struct{ColorSpace _fd .PdfObjectName ;BitsPerComponent int ;ColorComponents int ;Width int ;Height int ;Stream *_fd .PdfObjectStream ;PPI float64 ;};
|
|
|
|
// Optimize optimizes PDF objects to decrease PDF size.
|
|
func (_cef *Image )Optimize (objects []_fd .PdfObject )(_adg []_fd .PdfObject ,_aeec error ){if _cef .ImageQuality <=0{return objects ,nil ;};_eede :=_cad (objects );if len (_eede )==0{return objects ,nil ;};_fcfb :=make (map[_fd .PdfObject ]_fd .PdfObject );_fge :=make (map[_fd .PdfObject ]struct{});for _ ,_gefa :=range _eede {_gcg :=_gefa .Stream .PdfObjectDictionary .Get (_fd .PdfObjectName ("\u0053\u004d\u0061s\u006b"));_fge [_gcg ]=struct{}{};};for _eff ,_ada :=range _eede {_aeee :=_ada .Stream ;if _ ,_eef :=_fge [_aeee ];_eef {continue ;};_cfba ,_efa :=_fd .NewEncoderFromStream (_aeee );if _efa !=nil {_e .Log .Warning ("\u0045\u0072\u0072\u006f\u0072 \u0067\u0065\u0074\u0020\u0065\u006e\u0063\u006f\u0064\u0065\u0072\u0020\u0066o\u0072\u0020\u0074\u0068\u0065\u0020\u0069\u006d\u0061\u0067\u0065\u0020\u0073\u0074\u0072\u0065\u0061\u006d\u0020\u0025\u0073");continue ;};_bdbd ,_efa :=_cfba .DecodeStream (_aeee );if _efa !=nil {_e .Log .Warning ("\u0045\u0072\u0072\u006f\u0072\u0020\u0064\u0065\u0063\u006f\u0064\u0065\u0020\u0074\u0068e\u0020i\u006d\u0061\u0067\u0065\u0020\u0073\u0074\u0072\u0065\u0061\u006d\u0020\u0025\u0073");continue ;};_cefc :=_fd .NewDCTEncoder ();_cefc .ColorComponents =_ada .ColorComponents ;_cefc .Quality =_cef .ImageQuality ;_cefc .BitsPerComponent =_ada .BitsPerComponent ;_cefc .Width =_ada .Width ;_cefc .Height =_ada .Height ;_bga ,_efa :=_cefc .EncodeBytes (_bdbd );if _efa !=nil {_e .Log .Debug ("\u0045R\u0052\u004f\u0052\u003a\u0020\u0025v",_efa );return nil ,_efa ;};var _agef _fd .StreamEncoder ;_agef =_cefc ;{_cace :=_fd .NewFlateEncoder ();_efcc :=_fd .NewMultiEncoder ();_efcc .AddEncoder (_cace );_efcc .AddEncoder (_cefc );_deb ,_cfbd :=_efcc .EncodeBytes (_bdbd );if _cfbd !=nil {return nil ,_cfbd ;};if len (_deb )< len (_bga ){_e .Log .Debug ("\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 (_bga ),len (_deb ),len (_aeee .Stream ));_bga =_deb ;_agef =_efcc ;};};_cacd :=len (_aeee .Stream );if _cacd < len (_bga ){continue ;};_dcf :=&_fd .PdfObjectStream {Stream :_bga };_dcf .PdfObjectReference =_aeee .PdfObjectReference ;_dcf .PdfObjectDictionary =_fd .MakeDict ();_dcf .Merge (_aeee .PdfObjectDictionary );_dcf .Merge (_agef .MakeStreamDict ());_dcf .Set ("\u004c\u0065\u006e\u0067\u0074\u0068",_fd .MakeInteger (int64 (len (_bga ))));_fcfb [_aeee ]=_dcf ;_eede [_eff ].Stream =_dcf ;};_adg =make ([]_fd .PdfObject ,len (objects ));copy (_adg ,objects );_fgaf (_adg ,_fcfb );return _adg ,nil ;};
|
|
|
|
// Optimize optimizes PDF objects to decrease PDF size.
|
|
func (_fa *Chain )Optimize (objects []_fd .PdfObject )(_gd []_fd .PdfObject ,_cb error ){_gd =objects ;for _ ,_d :=range _fa ._cgd {_gd ,_cb =_d .Optimize (_gd );if _cb !=nil {return _gd ,_cb ;};};return _gd ,nil ;};
|
|
|
|
// CombineIdenticalIndirectObjects combines identical indirect objects.
|
|
// It implements interface model.Optimizer.
|
|
type CombineIdenticalIndirectObjects struct{};func _cga (_gcc *_fd .PdfObjectStream ,_egf []rune ,_ecfa []_gf .GlyphIndex )error {_gcc ,_eed :=_fd .GetStream (_gcc );if !_eed {_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 _cc .New ("\u0066\u006f\u006e\u0074fi\u006c\u0065\u0032\u0020\u006e\u006f\u0074\u0020\u0066\u006f\u0075\u006e\u0064");};_cfc ,_ffa :=_fd .DecodeStream (_gcc );if _ffa !=nil {_e .Log .Debug ("\u0044\u0065c\u006f\u0064\u0065 \u0065\u0072\u0072\u006f\u0072\u003a\u0020\u0025\u0076",_ffa );return _ffa ;};_ecff ,_ffa :=_gf .Parse (_cgf .NewReader (_cfc ));if _ffa !=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 (_gcc .Stream ));return _ffa ;};_cd :=_ecfa ;if len (_egf )> 0{_cdd :=_ecff .LookupRunes (_egf );_cd =append (_cd ,_cdd ...);};_ecff ,_ffa =_ecff .SubsetKeepIndices (_cd );if _ffa !=nil {_e .Log .Debug ("\u0045R\u0052\u004f\u0052\u0020s\u0075\u0062\u0073\u0065\u0074t\u0069n\u0067 \u0066\u006f\u006e\u0074\u003a\u0020\u0025v",_ffa );return _ffa ;};var _ea _cgf .Buffer ;_ffa =_ecff .Write (&_ea );if _ffa !=nil {_e .Log .Debug ("\u0045\u0052\u0052\u004fR \u0057\u0072\u0069\u0074\u0069\u006e\u0067\u0020\u0066\u006f\u006e\u0074\u003a\u0020%\u0076",_ffa );return _ffa ;};if _ea .Len ()> len (_cfc ){_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 ;};_eca ,_ffa :=_fd .MakeStream (_ea .Bytes (),_fd .NewFlateEncoder ());if _ffa !=nil {_e .Log .Debug ("\u0045\u0052\u0052\u004fR \u0057\u0072\u0069\u0074\u0069\u006e\u0067\u0020\u0066\u006f\u006e\u0074\u003a\u0020%\u0076",_ffa );return _ffa ;};*_gcc =*_eca ;_gcc .Set ("\u004ce\u006e\u0067\u0074\u0068\u0031",_fd .MakeInteger (int64 (_ea .Len ())));return nil ;};func _be (_ee *_fd .PdfObjectStream )error {_af ,_db :=_fd .DecodeStream (_ee );if _db !=nil {return _db ;};_bc :=_cf .NewContentStreamParser (string (_af ));_bd ,_db :=_bc .Parse ();if _db !=nil {return _db ;};_bd =_bgg (_bd );_aad :=_bd .Bytes ();if len (_aad )>=len (_af ){return nil ;};_dd ,_db :=_fd .MakeStream (_bd .Bytes (),_fd .NewFlateEncoder ());if _db !=nil {return _db ;};_ee .Stream =_dd .Stream ;_ee .Merge (_dd .PdfObjectDictionary );return nil ;};func _bgg (_ge *_cf .ContentStreamOperations )*_cf .ContentStreamOperations {if _ge ==nil {return nil ;};_ga :=_cf .ContentStreamOperations {};for _ ,_ed :=range *_ge {switch _ed .Operand {case "\u0042\u0044\u0043","\u0042\u004d\u0043","\u0045\u004d\u0043":continue ;case "\u0054\u006d":if len (_ed .Params )==6{if _bf ,_gdf :=_fd .GetNumbersAsFloat (_ed .Params );_gdf ==nil {if _bf [0]==1&&_bf [1]==0&&_bf [2]==0&&_bf [3]==1{_ed =&_cf .ContentStreamOperation {Params :[]_fd .PdfObject {_ed .Params [4],_ed .Params [5]},Operand :"\u0054\u0064"};};};};};_ga =append (_ga ,_ed );};return &_ga ;};
|
|
|
|
// New creates a optimizers chain from options.
|
|
func New (options Options )*Chain {_cgcc :=new (Chain );if options .CleanFonts ||options .SubsetFonts {_cgcc .Append (&CleanFonts {Subset :options .SubsetFonts });};if options .CleanContentstream {_cgcc .Append (new (CleanContentstream ));};if options .ImageUpperPPI > 0{_gae :=new (ImagePPI );_gae .ImageUpperPPI =options .ImageUpperPPI ;_cgcc .Append (_gae );};if options .ImageQuality > 0{_dcc :=new (Image );_dcc .ImageQuality =options .ImageQuality ;_cgcc .Append (_dcc );};if options .CombineDuplicateDirectObjects {_cgcc .Append (new (CombineDuplicateDirectObjects ));};if options .CombineDuplicateStreams {_cgcc .Append (new (CombineDuplicateStreams ));};if options .CombineIdenticalIndirectObjects {_cgcc .Append (new (CombineIdenticalIndirectObjects ));};if options .UseObjectStreams {_cgcc .Append (new (ObjectStreams ));};if options .CompressStreams {_cgcc .Append (new (CompressStreams ));};return _cgcc ;};
|
|
|
|
// Optimize optimizes PDF objects to decrease PDF size.
|
|
func (_bgef *CombineDuplicateDirectObjects )Optimize (objects []_fd .PdfObject )(_ddg []_fd .PdfObject ,_cbf error ){_bcge (objects );_bbe :=make (map[string ][]*_fd .PdfObjectDictionary );var _ggb func (_agac *_fd .PdfObjectDictionary );_ggb =func (_ggd *_fd .PdfObjectDictionary ){for _ ,_bfg :=range _ggd .Keys (){_cgg :=_ggd .Get (_bfg );if _ebf ,_fce :=_cgg .(*_fd .PdfObjectDictionary );_fce {_aag :=_a .New ();_aag .Write ([]byte (_ebf .WriteString ()));_baa :=string (_aag .Sum (nil ));_bbe [_baa ]=append (_bbe [_baa ],_ebf );_ggb (_ebf );};};};for _ ,_fdcg :=range objects {_eae ,_fac :=_fdcg .(*_fd .PdfIndirectObject );if !_fac {continue ;};if _agaf ,_cfbe :=_eae .PdfObject .(*_fd .PdfObjectDictionary );_cfbe {_ggb (_agaf );};};_afc :=make ([]_fd .PdfObject ,0,len (_bbe ));_acg :=make (map[_fd .PdfObject ]_fd .PdfObject );for _ ,_addf :=range _bbe {if len (_addf )< 2{continue ;};_aba :=_fd .MakeDict ();_aba .Merge (_addf [0]);_fbe :=_fd .MakeIndirectObject (_aba );_afc =append (_afc ,_fbe );for _eedf :=0;_eedf < len (_addf );_eedf ++{_fdbf :=_addf [_eedf ];_acg [_fdbf ]=_fbe ;};};_ddg =make ([]_fd .PdfObject ,len (objects ));copy (_ddg ,objects );_ddg =append (_afc ,_ddg ...);_fgaf (_ddg ,_acg );return _ddg ,nil ;};func _bbgd (_gbef _fd .PdfObject )(_efae string ,_cdde []_fd .PdfObject ){var _baae _cgf .Buffer ;switch _gca :=_gbef .(type ){case *_fd .PdfIndirectObject :_cdde =append (_cdde ,_gca );_gbef =_gca .PdfObject ;};switch _dacb :=_gbef .(type ){case *_fd .PdfObjectStream :if _bgcc ,_def :=_fd .DecodeStream (_dacb );_def ==nil {_baae .Write (_bgcc );_cdde =append (_cdde ,_dacb );};case *_fd .PdfObjectArray :for _ ,_debf :=range _dacb .Elements (){switch _feag :=_debf .(type ){case *_fd .PdfObjectStream :if _egcf ,_deee :=_fd .DecodeStream (_feag );_deee ==nil {_baae .Write (_egcf );_cdde =append (_cdde ,_feag );};};};};return _baae .String (),_cdde ;};func _bag (_bea _fd .PdfObject )[]content {if _bea ==nil {return nil ;};_aae ,_dbe :=_fd .GetArray (_bea );if !_dbe {_e .Log .Debug ("\u0041\u006e\u006e\u006fts\u0020\u006e\u006f\u0074\u0020\u0061\u006e\u0020\u0061\u0072\u0072\u0061\u0079");return nil ;};var _aga []content ;for _ ,_cbg :=range _aae .Elements (){_baf ,_dbdd :=_fd .GetDict (_cbg );if !_dbdd {_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 ;};_bec ,_dbdd :=_fd .GetDict (_baf .Get ("\u0041\u0050"));if !_dbdd {_e .Log .Debug ("\u004e\u006f\u0020\u0041P \u0065\u006e\u0074\u0072\u0079\u0020\u002d\u0020\u0073\u006b\u0069\u0070\u0070\u0069n\u0067");continue ;};_fbd :=_fd .TraceToDirectObject (_bec .Get ("\u004e"));if _fbd ==nil {_e .Log .Debug ("N\u006f\u0020\u004e\u0020en\u0074r\u0079\u0020\u002d\u0020\u0073k\u0069\u0070\u0070\u0069\u006e\u0067");continue ;};var _bad *_fd .PdfObjectStream ;switch _eba :=_fbd .(type ){case *_fd .PdfObjectDictionary :_edc ,_gff :=_fd .GetName (_baf .Get ("\u0041\u0053"));if !_gff {_e .Log .Debug ("\u004e\u006f\u0020\u0041S \u0065\u006e\u0074\u0072\u0079\u0020\u002d\u0020\u0073\u006b\u0069\u0070\u0070\u0069n\u0067");continue ;};_bad ,_gff =_fd .GetStream (_eba .Get (*_edc ));if !_gff {_e .Log .Debug ("\u0046o\u0072\u006d\u0020\u006eo\u0074\u0020\u0066\u006f\u0075n\u0064 \u002d \u0073\u006b\u0069\u0070\u0070\u0069\u006eg");continue ;};case *_fd .PdfObjectStream :_bad =_eba ;};if _bad ==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 ;};_bgfb ,_gfd :=_fe .NewXObjectFormFromStream (_bad );if _gfd !=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",_gfd );continue ;};_gfe ,_gfd :=_bgfb .GetContentStream ();if _gfd !=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",_gfd );continue ;};_aga =append (_aga ,content {_ce :string (_gfe ),_fee :_bgfb .Resources });};return _aga ;};func _cad (_cfec []_fd .PdfObject )[]*imageInfo {_cedc :=_fd .PdfObjectName ("\u0053u\u0062\u0074\u0079\u0070\u0065");_bgcg :=make (map[*_fd .PdfObjectStream ]struct{});var _dcab error ;var _fga []*imageInfo ;for _ ,_cca :=range _cfec {_fdba ,_dgcf :=_fd .GetStream (_cca );if !_dgcf {continue ;};if _ ,_bggg :=_bgcg [_fdba ];_bggg {continue ;};_bgcg [_fdba ]=struct{}{};_dbgb :=_fdba .PdfObjectDictionary .Get (_cedc );_dcd ,_dgcf :=_fd .GetName (_dbgb );if !_dgcf ||string (*_dcd )!="\u0049\u006d\u0061g\u0065"{continue ;};_eaf :=&imageInfo {BitsPerComponent :8,Stream :_fdba };if _eaf .ColorSpace ,_dcab =_fe .DetermineColorspaceNameFromPdfObject (_fdba .PdfObjectDictionary .Get ("\u0043\u006f\u006c\u006f\u0072\u0053\u0070\u0061\u0063\u0065"));_dcab !=nil {_e .Log .Error ("\u0045\u0072\u0072\u006f\u0072\u0020\u0064\u0065\u0074\u0065r\u006d\u0069\u006e\u0065\u0020\u0063\u006fl\u006f\u0072\u0020\u0073\u0070\u0061\u0063\u0065\u0020\u0025\u0073",_dcab );continue ;};if _ffeef ,_dae :=_fd .GetIntVal (_fdba .PdfObjectDictionary .Get ("\u0042\u0069t\u0073\u0050\u0065r\u0043\u006f\u006d\u0070\u006f\u006e\u0065\u006e\u0074"));_dae {_eaf .BitsPerComponent =_ffeef ;};if _acgg ,_efe :=_fd .GetIntVal (_fdba .PdfObjectDictionary .Get ("\u0057\u0069\u0064t\u0068"));_efe {_eaf .Width =_acgg ;};if _dcb ,_aadb :=_fd .GetIntVal (_fdba .PdfObjectDictionary .Get ("\u0048\u0065\u0069\u0067\u0068\u0074"));_aadb {_eaf .Height =_dcb ;};switch _eaf .ColorSpace {case "\u0044e\u0076\u0069\u0063\u0065\u0052\u0047B":_eaf .ColorComponents =3;case "\u0044\u0065\u0076\u0069\u0063\u0065\u0047\u0072\u0061\u0079":_eaf .ColorComponents =1;default:_e .Log .Warning ("\u004f\u0070\u0074\u0069\u006d\u0069\u007a\u0061t\u0069\u006f\u006e i\u0073\u0020\u006e\u006f\u0074\u0020s\u0075\u0070\u0070\u006f\u0072\u0074\u0065\u0064\u0020\u0066\u006f\u0072\u0020\u0063\u006fl\u006f\u0072\u0020\u0073\u0070\u0061\u0063\u0065 \u0025\u0073",_eaf .ColorSpace );continue ;};_fga =append (_fga ,_eaf );};return _fga ;};func _fbda (_dac *_fe .XObjectImage ,_daf imageModifications )error {_eeba ,_bdg :=_dac .ToImage ();if _bdg !=nil {return _bdg ;};if _daf .Scale !=0{_eeba ,_bdg =_caf (_eeba ,_daf .Scale );if _bdg !=nil {return _bdg ;};};if _daf .Encoding !=nil {_dac .Filter =_daf .Encoding ;};_gecdf :=_fd .MakeDict ();_gecdf .Set ("\u0051u\u0061\u006c\u0069\u0074\u0079",_fd .MakeInteger (100));_gecdf .Set ("\u0050r\u0065\u0064\u0069\u0063\u0074\u006fr",_fd .MakeInteger (1));_dac .Decode =nil ;if _bdg =_dac .SetImage (_eeba ,nil );_bdg !=nil {return _bdg ;};_dac .ToPdfObject ();return nil ;};
|
|
|
|
// Optimize optimizes PDF objects to decrease PDF size.
|
|
func (_ceb *CombineDuplicateStreams )Optimize (objects []_fd .PdfObject )(_bfb []_fd .PdfObject ,_fcfe error ){_bab :=make (map[_fd .PdfObject ]_fd .PdfObject );_gecd :=make (map[_fd .PdfObject ]struct{});_ebaa :=make (map[string ][]*_fd .PdfObjectStream );for _ ,_gccb :=range objects {if _gfg ,_bcg :=_gccb .(*_fd .PdfObjectStream );_bcg {_bcgf :=_a .New ();_bcgf .Write (_gfg .Stream );_afd :=string (_bcgf .Sum (nil ));_ebaa [_afd ]=append (_ebaa [_afd ],_gfg );};};for _ ,_eeb :=range _ebaa {if len (_eeb )< 2{continue ;};_bdbe :=_eeb [0];for _edac :=1;_edac < len (_eeb );_edac ++{_ggab :=_eeb [_edac ];_bab [_ggab ]=_bdbe ;_gecd [_ggab ]=struct{}{};};};_bfb =make ([]_fd .PdfObject ,0,len (objects )-len (_gecd ));for _ ,_addc :=range objects {if _ ,_cgdg :=_gecd [_addc ];_cgdg {continue ;};_bfb =append (_bfb ,_addc );};_fgaf (_bfb ,_bab );return _bfb ,nil ;};
|
|
|
|
// ObjectStreams groups PDF objects to object streams.
|
|
// It implements interface model.Optimizer.
|
|
type ObjectStreams struct{};
|
|
|
|
// CompressStreams compresses uncompressed streams.
|
|
// It implements interface model.Optimizer.
|
|
type CompressStreams struct{};type imageModifications struct{Scale float64 ;Encoding _fd .StreamEncoder ;};
|
|
|
|
// 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 _bcge (_gdbg []_fd .PdfObject ){for _abg ,_daaf :=range _gdbg {switch _bfcg :=_daaf .(type ){case *_fd .PdfIndirectObject :_bfcg .ObjectNumber =int64 (_abg +1);_bfcg .GenerationNumber =0;case *_fd .PdfObjectStream :_bfcg .ObjectNumber =int64 (_abg +1);_bfcg .GenerationNumber =0;case *_fd .PdfObjectStreams :_bfcg .ObjectNumber =int64 (_abg +1);_bfcg .GenerationNumber =0;};};};
|
|
|
|
// Chain allows to use sequence of optimizers.
|
|
// It implements interface model.Optimizer.
|
|
type Chain struct{_cgd []_fe .Optimizer };func _efag (_gegc []_fd .PdfObject )objectStructure {_fag :=objectStructure {};_ccfg :=false ;for _ ,_baca :=range _gegc {switch _cdab :=_baca .(type ){case *_fd .PdfIndirectObject :_abd ,_cfcc :=_fd .GetDict (_cdab );if !_cfcc {continue ;};_gabc ,_cfcc :=_fd .GetName (_abd .Get ("\u0054\u0079\u0070\u0065"));if !_cfcc {continue ;};switch _gabc .String (){case "\u0043a\u0074\u0061\u006c\u006f\u0067":_fag ._ddd =_abd ;_ccfg =true ;};};if _ccfg {break ;};};if !_ccfg {return _fag ;};_ffb ,_bbg :=_fd .GetDict (_fag ._ddd .Get ("\u0050\u0061\u0067e\u0073"));if !_bbg {return _fag ;};_fag ._bfdc =_ffb ;_addcd ,_bbg :=_fd .GetArray (_ffb .Get ("\u004b\u0069\u0064\u0073"));if !_bbg {return _fag ;};for _ ,_egfg :=range _addcd .Elements (){_bfca ,_afdg :=_fd .GetIndirect (_egfg );if !_afdg {break ;};_fag ._aaf =append (_fag ._aaf ,_bfca );};return _fag ;};
|
|
|
|
// Optimize optimizes PDF objects to decrease PDF size.
|
|
func (_dffb *ImagePPI )Optimize (objects []_fd .PdfObject )(_agad []_fd .PdfObject ,_ffef error ){if _dffb .ImageUpperPPI <=0{return objects ,nil ;};_ead :=_cad (objects );if len (_ead )==0{return objects ,nil ;};_eaeb :=make (map[_fd .PdfObject ]struct{});for _ ,_ccb :=range _ead {_ebcd :=_ccb .Stream .PdfObjectDictionary .Get (_fd .PdfObjectName ("\u0053\u004d\u0061s\u006b"));_eaeb [_ebcd ]=struct{}{};};_egd :=make (map[*_fd .PdfObjectStream ]*imageInfo );for _ ,_ega :=range _ead {_egd [_ega .Stream ]=_ega ;};var _daga *_fd .PdfObjectDictionary ;for _ ,_fbg :=range objects {if _caff ,_cacg :=_fd .GetDict (_fbg );_daga ==nil &&_cacg {if _faa ,_gaa :=_fd .GetName (_caff .Get (_fd .PdfObjectName ("\u0054\u0079\u0070\u0065")));_gaa &&*_faa =="\u0043a\u0074\u0061\u006c\u006f\u0067"{_daga =_caff ;};};};if _daga ==nil {return objects ,nil ;};_cba ,_bda :=_fd .GetDict (_daga .Get (_fd .PdfObjectName ("\u0050\u0061\u0067e\u0073")));if !_bda {return objects ,nil ;};_ged ,_ecdc :=_fd .GetArray (_cba .Get (_fd .PdfObjectName ("\u004b\u0069\u0064\u0073")));if !_ecdc {return objects ,nil ;};_afeeg :=make (map[string ]*imageInfo );for _ ,_faad :=range _ged .Elements (){_gad ,_dfcd :=_fd .GetDict (_faad );if !_dfcd {continue ;};_beeg ,_eab :=_fd .GetArray (_gad .Get ("\u0043\u006f\u006e\u0074\u0065\u006e\u0074\u0073"));if !_eab {continue ;};_fbcf ,_fec :=_fd .GetDict (_gad .Get ("\u0052e\u0073\u006f\u0075\u0072\u0063\u0065s"));if !_fec {continue ;};_adge ,_bfbb :=_fd .GetDict (_fbcf .Get ("\u0058O\u0062\u006a\u0065\u0063\u0074"));if !_bfbb {continue ;};_bgbe :=_adge .Keys ();for _ ,_aead :=range _bgbe {if _agg ,_ceec :=_fd .GetStream (_adge .Get (_aead ));_ceec {if _gddb ,_bff :=_egd [_agg ];_bff {_afeeg [string (_aead )]=_gddb ;};};};for _ ,_dbed :=range _beeg .Elements (){if _cadb ,_cdc :=_fd .GetStream (_dbed );_cdc {_feg ,_adfa :=_fd .NewEncoderFromStream (_cadb );if _adfa !=nil {return nil ,_adfa ;};_aeb ,_adfa :=_feg .DecodeStream (_cadb );if _adfa !=nil {return nil ,_adfa ;};_fdcb :=_cf .NewContentStreamParser (string (_aeb ));_dcbe ,_adfa :=_fdcb .Parse ();if _adfa !=nil {return nil ,_adfa ;};_cdf ,_daaa :=1.0,1.0;for _ ,_efee :=range *_dcbe {if _efee .Operand =="\u0051"{_cdf ,_daaa =1.0,1.0;};if _efee .Operand =="\u0063\u006d"&&len (_efee .Params )==6{if _ddf ,_bcc :=_fd .GetFloatVal (_efee .Params [0]);_bcc {_cdf =_cdf *_ddf ;};if _faca ,_bed :=_fd .GetFloatVal (_efee .Params [3]);_bed {_daaa =_daaa *_faca ;};if _fefc ,_gab :=_fd .GetIntVal (_efee .Params [0]);_gab {_cdf =_cdf *float64 (_fefc );};if _aaef ,_eggf :=_fd .GetIntVal (_efee .Params [3]);_eggf {_daaa =_daaa *float64 (_aaef );};};if _efee .Operand =="\u0044\u006f"&&len (_efee .Params )==1{_cfg ,_aecb :=_fd .GetName (_efee .Params [0]);if !_aecb {continue ;};if _gcgd ,_geed :=_afeeg [string (*_cfg )];_geed {_gecg ,_dge :=_cdf /72.0,_daaa /72.0;_cfece ,_dfcb :=float64 (_gcgd .Width )/_gecg ,float64 (_gcgd .Height )/_dge ;if _gecg ==0||_dge ==0{_cfece =72.0;_dfcb =72.0;};_gcgd .PPI =_ff .Max (_gcgd .PPI ,_cfece );_gcgd .PPI =_ff .Max (_gcgd .PPI ,_dfcb );};};};};};};for _ ,_gcbg :=range _ead {if _ ,_ade :=_eaeb [_gcbg .Stream ];_ade {continue ;};if _gcbg .PPI <=_dffb .ImageUpperPPI {continue ;};_bfd ,_cda :=_fe .NewXObjectImageFromStream (_gcbg .Stream );if _cda !=nil {return nil ,_cda ;};var _ecfff imageModifications ;_ecfff .Scale =_dffb .ImageUpperPPI /_gcbg .PPI ;if _gcbg .BitsPerComponent ==1&&_gcbg .ColorComponents ==1{_eec :=_ff .Round (_gcbg .PPI /_dffb .ImageUpperPPI );_ggadf :=_aa .NextPowerOf2 (uint (_eec ));if _aa .InDelta (float64 (_ggadf ),1/_ecfff .Scale ,0.3){_ecfff .Scale =float64 (1)/float64 (_ggadf );};if _ ,_dab :=_bfd .Filter .(*_fd .JBIG2Encoder );!_dab {_ecfff .Encoding =_fd .NewJBIG2Encoder ();};};if _cda =_fbda (_bfd ,_ecfff );_cda !=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",_cda );continue ;};_ecfff .Encoding =nil ;if _ebae ,_debb :=_fd .GetStream (_gcbg .Stream .PdfObjectDictionary .Get (_fd .PdfObjectName ("\u0053\u004d\u0061s\u006b")));_debb {_cbd ,_bdf :=_fe .NewXObjectImageFromStream (_ebae );if _bdf !=nil {return nil ,_bdf ;};if _bdf =_fbda (_cbd ,_ecfff );_bdf !=nil {return nil ,_bdf ;};};};return objects ,nil ;};type objectStructure struct{_ddd *_fd .PdfObjectDictionary ;_bfdc *_fd .PdfObjectDictionary ;_aaf []*_fd .PdfIndirectObject ;};
|
|
|
|
// 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{};
|
|
|
|
// CombineDuplicateDirectObjects combines duplicated direct objects by its data hash.
|
|
// It implements interface model.Optimizer.
|
|
type CombineDuplicateDirectObjects struct{};func _fgaf (_gdff []_fd .PdfObject ,_eag map[_fd .PdfObject ]_fd .PdfObject ){if len (_eag )==0{return ;};for _fea ,_bfdd :=range _gdff {if _gfag ,_gbf :=_eag [_bfdd ];_gbf {_gdff [_fea ]=_gfag ;continue ;};_eag [_bfdd ]=_bfdd ;switch _cfcg :=_bfdd .(type ){case *_fd .PdfObjectArray :_bccf :=make ([]_fd .PdfObject ,_cfcg .Len ());copy (_bccf ,_cfcg .Elements ());_fgaf (_bccf ,_eag );for _dgdec ,_ecfd :=range _bccf {_cfcg .Set (_dgdec ,_ecfd );};case *_fd .PdfObjectStreams :_fgaf (_cfcg .Elements (),_eag );case *_fd .PdfObjectStream :_aadd :=[]_fd .PdfObject {_cfcg .PdfObjectDictionary };_fgaf (_aadd ,_eag );_cfcg .PdfObjectDictionary =_aadd [0].(*_fd .PdfObjectDictionary );case *_fd .PdfObjectDictionary :_aaeg :=_cfcg .Keys ();_dga :=make ([]_fd .PdfObject ,len (_aaeg ));for _bfc ,_fbb :=range _aaeg {_dga [_bfc ]=_cfcg .Get (_fbb );};_fgaf (_dga ,_eag );for _bfdb ,_dccc :=range _aaeg {_cfcg .Set (_dccc ,_dga [_bfdb ]);};case *_fd .PdfIndirectObject :_cgdc :=[]_fd .PdfObject {_cfcg .PdfObject };_fgaf (_cgdc ,_eag );_cfcg .PdfObject =_cgdc [0];};};};
|
|
|
|
// Optimize optimizes PDF objects to decrease PDF size.
|
|
func (_ecab *CleanFonts )Optimize (objects []_fd .PdfObject )(_fcb []_fd .PdfObject ,_add error ){var _dca map[*_fd .PdfObjectStream ]struct{};if _ecab .Subset {var _bdc error ;_dca ,_bdc =_dgdf (objects );if _bdc !=nil {return nil ,_bdc ;};};for _ ,_gfa :=range objects {_ef ,_egg :=_fd .GetStream (_gfa );if !_egg {continue ;};if _ ,_bdb :=_dca [_ef ];_bdb {continue ;};_afee ,_bgge :=_fd .NewEncoderFromStream (_ef );if _bgge !=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",_bgge );continue ;};_cag ,_bgge :=_afee .DecodeStream (_ef );if _bgge !=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",_bgge );continue ;};if len (_cag )< 4{continue ;};_ddb :=string (_cag [:4]);if _ddb =="\u004f\u0054\u0054\u004f"{continue ;};if _ddb !="\u0000\u0001\u0000\u0000"&&_ddb !="\u0074\u0072\u0075\u0065"{continue ;};_eaa ,_bgge :=_gf .Parse (_cgf .NewReader (_cag ));if _bgge !=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",_bgge );continue ;};_bgge =_eaa .Optimize ();if _bgge !=nil {continue ;};var _fcc _cgf .Buffer ;_bgge =_eaa .Write (&_fcc );if _bgge !=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",_bgge );continue ;};if _fcc .Len ()> len (_cag ){_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 ;};_fda ,_bgge :=_fd .MakeStream (_fcc .Bytes (),_fd .NewFlateEncoder ());if _bgge !=nil {continue ;};*_ef =*_fda ;_ef .Set ("\u004ce\u006e\u0067\u0074\u0068\u0031",_fd .MakeInteger (int64 (_fcc .Len ())));};return objects ,nil ;};func _caf (_ebcb *_fe .Image ,_fba float64 )(*_fe .Image ,error ){_ccd ,_egc :=_ebcb .ToGoImage ();if _egc !=nil {return nil ,_egc ;};var _ggcd _aa .Image ;_babf ,_gdgc :=_ccd .(*_aa .Monochrome );if _gdgc {if _egc =_babf .ResolveDecode ();_egc !=nil {return nil ,_egc ;};_ggcd ,_egc =_babf .Scale (_fba );if _egc !=nil {return nil ,_egc ;};}else {_daa :=int (_ff .RoundToEven (float64 (_ebcb .Width )*_fba ));_gbcf :=int (_ff .RoundToEven (float64 (_ebcb .Height )*_fba ));_ggcd ,_egc =_aa .NewImage (_daa ,_gbcf ,int (_ebcb .BitsPerComponent ),_ebcb .ColorComponents ,nil ,nil ,nil );if _egc !=nil {return nil ,_egc ;};_c .CatmullRom .Scale (_ggcd ,_ggcd .Bounds (),_ccd ,_ccd .Bounds (),_c .Over ,&_c .Options {});};_gcde :=_ggcd .Base ();_dcbg :=&_fe .Image {Width :int64 (_gcde .Width ),Height :int64 (_gcde .Height ),BitsPerComponent :int64 (_gcde .BitsPerComponent ),ColorComponents :_gcde .ColorComponents ,Data :_gcde .Data };_dcbg .SetDecode (_gcde .Decode );_dcbg .SetAlpha (_gcde .Alpha );return _dcbg ,nil ;};type content struct{_ce string ;_fee *_fe .PdfPageResources ;};
|
|
|
|
// 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 (_gc *CleanContentstream )Optimize (objects []_fd .PdfObject )(_ae []_fd .PdfObject ,_cgc error ){_df :=map[*_fd .PdfObjectStream ]struct{}{};var _fc []*_fd .PdfObjectStream ;_dg :=func (_gfc *_fd .PdfObjectStream ){if _ ,_ab :=_df [_gfc ];!_ab {_df [_gfc ]=struct{}{};_fc =append (_fc ,_gfc );};};for _ ,_fb :=range objects {switch _eda :=_fb .(type ){case *_fd .PdfIndirectObject :switch _gg :=_eda .PdfObject .(type ){case *_fd .PdfObjectDictionary :if _bgf ,_aef :=_fd .GetName (_gg .Get ("\u0054\u0079\u0070\u0065"));!_aef ||_bgf .String ()!="\u0050\u0061\u0067\u0065"{continue ;};if _cfb ,_gb :=_fd .GetStream (_gg .Get ("\u0043\u006f\u006e\u0074\u0065\u006e\u0074\u0073"));_gb {_dg (_cfb );}else if _ac ,_gbc :=_fd .GetArray (_gg .Get ("\u0043\u006f\u006e\u0074\u0065\u006e\u0074\u0073"));_gbc {for _ ,_ffe :=range _ac .Elements (){if _gef ,_bgc :=_fd .GetStream (_ffe );_bgc {_dg (_gef );};};};};case *_fd .PdfObjectStream :if _edd ,_dgd :=_fd .GetName (_eda .Get ("\u0054\u0079\u0070\u0065"));!_dgd ||_edd .String ()!="\u0058O\u0062\u006a\u0065\u0063\u0074"{continue ;};if _fg ,_eb :=_fd .GetName (_eda .Get ("\u0053u\u0062\u0074\u0079\u0070\u0065"));!_eb ||_fg .String ()!="\u0046\u006f\u0072\u006d"{continue ;};_dg (_eda );};};for _ ,_fff :=range _fc {_cgc =_be (_fff );if _cgc !=nil {return nil ,_cgc ;};};return objects ,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 ;};
|
|
|
|
// Optimize optimizes PDF objects to decrease PDF size.
|
|
func (_bcb *CompressStreams )Optimize (objects []_fd .PdfObject )(_cac []_fd .PdfObject ,_gdg error ){_cac =make ([]_fd .PdfObject ,len (objects ));copy (_cac ,objects );for _ ,_fffc :=range objects {_bbc ,_da :=_fd .GetStream (_fffc );if !_da {continue ;};if _bca :=_bbc .Get ("\u0046\u0069\u006c\u0074\u0065\u0072");_bca !=nil {if _ ,_fbc :=_fd .GetName (_bca );_fbc {continue ;};if _aeeb ,_ebg :=_fd .GetArray (_bca );_ebg &&_aeeb .Len ()> 0{continue ;};};_adf :=_fd .NewFlateEncoder ();var _dba []byte ;_dba ,_gdg =_adf .EncodeBytes (_bbc .Stream );if _gdg !=nil {return _cac ,_gdg ;};_efc :=_adf .MakeStreamDict ();if len (_dba )+len (_efc .WriteString ())< len (_bbc .Stream ){_bbc .Stream =_dba ;_bbc .PdfObjectDictionary .Merge (_efc );_bbc .PdfObjectDictionary .Set ("\u004c\u0065\u006e\u0067\u0074\u0068",_fd .MakeInteger (int64 (len (_bbc .Stream ))));};};return _cac ,nil ;};func _dgdf (_ec []_fd .PdfObject )(_ag map[*_fd .PdfObjectStream ]struct{},_ba error ){_ag =map[*_fd .PdfObjectStream ]struct{}{};_acd :=map[*_fe .PdfFont ]struct{}{};_gga :=_efag (_ec );for _ ,_bae :=range _gga ._aaf {_aadge ,_aee :=_fd .GetDict (_bae .PdfObject );if !_aee {continue ;};_geg ,_aee :=_fd .GetDict (_aadge .Get ("\u0052e\u0073\u006f\u0075\u0072\u0063\u0065s"));if !_aee {continue ;};_afef ,_ :=_bbgd (_aadge .Get ("\u0043\u006f\u006e\u0074\u0065\u006e\u0074\u0073"));_gdd ,_dbg :=_fe .NewPdfPageResourcesFromDict (_geg );if _dbg !=nil {return nil ,_dbg ;};_aeg :=[]content {{_ce :_afef ,_fee :_gdd }};_gdfa :=_bag (_aadge .Get ("\u0041\u006e\u006e\u006f\u0074\u0073"));if _gdfa !=nil {_aeg =append (_aeg ,_gdfa ...);};for _ ,_ccf :=range _aeg {_bde ,_bge :=_cg .NewFromContents (_ccf ._ce ,_ccf ._fee );if _bge !=nil {return nil ,_bge ;};_de ,_ ,_ ,_bge :=_bde .ExtractPageText ();if _bge !=nil {return nil ,_bge ;};for _ ,_cfe :=range _de .Marks ().Elements (){if _cfe .Font ==nil {continue ;};if _ ,_dec :=_acd [_cfe .Font ];!_dec {_acd [_cfe .Font ]=struct{}{};};};};};_gcd :=map[*_fd .PdfObjectStream ][]*_fe .PdfFont {};for _ca :=range _acd {_aea :=_ca .FontDescriptor ();if _aea ==nil ||_aea .FontFile2 ==nil {continue ;};_aec ,_dgb :=_fd .GetStream (_aea .FontFile2 );if !_dgb {continue ;};_gcd [_aec ]=append (_gcd [_aec ],_ca );};for _ecd :=range _gcd {var _ffg []rune ;var _fdb []_gf .GlyphIndex ;for _ ,_aaa :=range _gcd [_ecd ]{switch _gec :=_aaa .Encoder ().(type ){case *_g .IdentityEncoder :_dc :=_gec .RegisteredRunes ();_acf :=make ([]_gf .GlyphIndex ,len (_dc ));for _ggc ,_fcf :=range _dc {_acf [_ggc ]=_gf .GlyphIndex (_fcf );};_fdb =append (_fdb ,_acf ...);case *_g .TrueTypeFontEncoder :_dfd :=_gec .RegisteredRunes ();_ffg =append (_ffg ,_dfd ...);case _g .SimpleEncoder :_gbe :=_gec .Charcodes ();for _ ,_fdg :=range _gbe {_ad ,_bb :=_gec .CharcodeToRune (_fdg );if !_bb {_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",_fdg );continue ;};_ffg =append (_ffg ,_ad );};};};_ba =_cga (_ecd ,_ffg ,_fdb );if _ba !=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",_ba );return nil ,_ba ;};_ag [_ecd ]=struct{}{};};return _ag ,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 ;};
|
|
|
|
// 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 ;}; |