2020-08-27 21:45:09 +00:00
|
|
|
//
|
|
|
|
// 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/
|
|
|
|
|
2021-05-11 00:01:27 +00:00
|
|
|
package optimize ;import (_ba "bytes";_d "crypto/md5";_cc "errors";_e "github.com/unidoc/unipdf/v3/common";_fb "github.com/unidoc/unipdf/v3/contentstream";_g "github.com/unidoc/unipdf/v3/core";_gg "github.com/unidoc/unipdf/v3/extractor";_b "github.com/unidoc/unipdf/v3/internal/imageutil";
|
|
|
|
_c "github.com/unidoc/unipdf/v3/internal/textencoding";_dd "github.com/unidoc/unipdf/v3/model";_eg "github.com/unidoc/unitype";_a "golang.org/x/image/draw";_ag "math";);
|
2021-04-17 13:46:54 +00:00
|
|
|
|
|
|
|
// Optimize optimizes PDF objects to decrease PDF size.
|
2021-05-11 00:01:27 +00:00
|
|
|
func (_dbf *CombineDuplicateStreams )Optimize (objects []_g .PdfObject )(_fda []_g .PdfObject ,_dcd error ){_ead :=make (map[_g .PdfObject ]_g .PdfObject );_fbbe :=make (map[_g .PdfObject ]struct{});_gbf :=make (map[string ][]*_g .PdfObjectStream );for _ ,_dcbc :=range objects {if _dgg ,_aaa :=_dcbc .(*_g .PdfObjectStream );
|
|
|
|
_aaa {_fgga :=_d .New ();_fgga .Write (_dgg .Stream );_afb :=string (_fgga .Sum (nil ));_gbf [_afb ]=append (_gbf [_afb ],_dgg );};};for _ ,_bfg :=range _gbf {if len (_bfg )< 2{continue ;};_dcdd :=_bfg [0];for _ddf :=1;_ddf < len (_bfg );_ddf ++{_baaa :=_bfg [_ddf ];
|
|
|
|
_ead [_baaa ]=_dcdd ;_fbbe [_baaa ]=struct{}{};};};_fda =make ([]_g .PdfObject ,0,len (objects )-len (_fbbe ));for _ ,_gcgb :=range objects {if _ ,_fccf :=_fbbe [_gcgb ];_fccf {continue ;};_fda =append (_fda ,_gcgb );};_fbae (_fda ,_ead );return _fda ,nil ;
|
|
|
|
};func _cge (_ad *_fb .ContentStreamOperations )*_fb .ContentStreamOperations {if _ad ==nil {return nil ;};_ge :=_fb .ContentStreamOperations {};for _ ,_db :=range *_ad {switch _db .Operand {case "\u0042\u0044\u0043","\u0042\u004d\u0043","\u0045\u004d\u0043":continue ;
|
|
|
|
case "\u0054\u006d":if len (_db .Params )==6{if _cae ,_fbe :=_g .GetNumbersAsFloat (_db .Params );_fbe ==nil {if _cae [0]==1&&_cae [1]==0&&_cae [2]==0&&_cae [3]==1{_db =&_fb .ContentStreamOperation {Params :[]_g .PdfObject {_db .Params [4],_db .Params [5]},Operand :"\u0054\u0064"};
|
|
|
|
};};};};_ge =append (_ge ,_db );};return &_ge ;};func _bfd (_bdbc []_g .PdfObject ){for _degb ,_abdd :=range _bdbc {switch _dcgd :=_abdd .(type ){case *_g .PdfIndirectObject :_dcgd .ObjectNumber =int64 (_degb +1);_dcgd .GenerationNumber =0;case *_g .PdfObjectStream :_dcgd .ObjectNumber =int64 (_degb +1);
|
|
|
|
_dcgd .GenerationNumber =0;case *_g .PdfObjectStreams :_dcgd .ObjectNumber =int64 (_degb +1);_dcgd .GenerationNumber =0;};};};
|
2021-04-23 20:28:14 +00:00
|
|
|
|
|
|
|
// Optimize optimizes PDF objects to decrease PDF size.
|
2021-05-11 00:01:27 +00:00
|
|
|
func (_bee *ObjectStreams )Optimize (objects []_g .PdfObject )(_adccd []_g .PdfObject ,_gacb error ){_dcad :=&_g .PdfObjectStreams {};_afda :=make ([]_g .PdfObject ,0,len (objects ));for _ ,_bgab :=range objects {if _fbcg ,_dde :=_bgab .(*_g .PdfIndirectObject );
|
|
|
|
_dde &&_fbcg .GenerationNumber ==0{_dcad .Append (_bgab );}else {_afda =append (_afda ,_bgab );};};if _dcad .Len ()==0{return _afda ,nil ;};_adccd =make ([]_g .PdfObject ,0,len (_afda )+_dcad .Len ()+1);if _dcad .Len ()> 1{_adccd =append (_adccd ,_dcad );
|
|
|
|
};_adccd =append (_adccd ,_dcad .Elements ()...);_adccd =append (_adccd ,_afda ...);return _adccd ,nil ;};
|
2021-04-23 20:28:14 +00:00
|
|
|
|
2021-05-11 00:01:27 +00:00
|
|
|
// Optimize optimizes PDF objects to decrease PDF size.
|
|
|
|
func (_fg *CleanFonts )Optimize (objects []_g .PdfObject )(_fbb []_g .PdfObject ,_ceb error ){var _bbe map[*_g .PdfObjectStream ]struct{};if _fg .Subset {var _fca error ;_bbe ,_fca =_de (objects );if _fca !=nil {return nil ,_fca ;};};for _ ,_daf :=range objects {_fgg ,_gce :=_g .GetStream (_daf );
|
|
|
|
if !_gce {continue ;};if _ ,_aac :=_bbe [_fgg ];_aac {continue ;};_bdd ,_ga :=_g .NewEncoderFromStream (_fgg );if _ga !=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",_ga );
|
|
|
|
continue ;};_aeg ,_ga :=_bdd .DecodeStream (_fgg );if _ga !=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",_ga );
|
|
|
|
continue ;};if len (_aeg )< 4{continue ;};_caad :=string (_aeg [:4]);if _caad =="\u004f\u0054\u0054\u004f"{continue ;};if _caad !="\u0000\u0001\u0000\u0000"&&_caad !="\u0074\u0072\u0075\u0065"{continue ;};_fdd ,_ga :=_eg .Parse (_ba .NewReader (_aeg ));
|
|
|
|
if _ga !=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",_ga );continue ;};_ga =_fdd .Optimize ();
|
|
|
|
if _ga !=nil {continue ;};var _ebe _ba .Buffer ;_ga =_fdd .Write (&_ebe );if _ga !=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",_ga );
|
|
|
|
continue ;};if _ebe .Len ()> len (_aeg ){_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 ;};_daa ,_ga :=_g .MakeStream (_ebe .Bytes (),_g .NewFlateEncoder ());if _ga !=nil {continue ;};*_fgg =*_daa ;_fgg .Set ("\u004ce\u006e\u0067\u0074\u0068\u0031",_g .MakeInteger (int64 (_ebe .Len ())));};return objects ,nil ;};
|
|
|
|
|
|
|
|
// CompressStreams compresses uncompressed streams.
|
2021-04-23 20:28:14 +00:00
|
|
|
// It implements interface model.Optimizer.
|
2021-05-11 00:01:27 +00:00
|
|
|
type CompressStreams struct{};
|
2021-04-23 20:28:14 +00:00
|
|
|
|
2021-05-11 00:01:27 +00:00
|
|
|
// 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 ;};
|
2021-04-23 20:28:14 +00:00
|
|
|
|
|
|
|
// Optimize optimizes PDF objects to decrease PDF size.
|
2021-05-11 00:01:27 +00:00
|
|
|
func (_cg *Chain )Optimize (objects []_g .PdfObject )(_ac []_g .PdfObject ,_bg error ){_ac =objects ;for _ ,_ae :=range _cg ._ed {_ac ,_bg =_ae .Optimize (_ac );if _bg !=nil {return _ac ,_bg ;};};return _ac ,nil ;};type objectStructure struct{_dcge *_g .PdfObjectDictionary ;
|
|
|
|
_cdcc *_g .PdfObjectDictionary ;_eade []*_g .PdfIndirectObject ;};
|
2021-04-23 20:28:14 +00:00
|
|
|
|
2021-05-11 00:01:27 +00:00
|
|
|
// Optimize optimizes PDF objects to decrease PDF size.
|
|
|
|
func (_gfd *CleanContentstream )Optimize (objects []_g .PdfObject )(_fbg []_g .PdfObject ,_ef error ){_cga :=map[*_g .PdfObjectStream ]struct{}{};var _adc []*_g .PdfObjectStream ;_bgc :=func (_eb *_g .PdfObjectStream ){if _ ,_caa :=_cga [_eb ];!_caa {_cga [_eb ]=struct{}{};
|
|
|
|
_adc =append (_adc ,_eb );};};for _ ,_ee :=range objects {switch _bb :=_ee .(type ){case *_g .PdfIndirectObject :switch _dc :=_bb .PdfObject .(type ){case *_g .PdfObjectDictionary :if _dbg ,_ddb :=_g .GetName (_dc .Get ("\u0054\u0079\u0070\u0065"));!_ddb ||_dbg .String ()!="\u0050\u0061\u0067\u0065"{continue ;
|
|
|
|
};if _aae ,_ebg :=_g .GetStream (_dc .Get ("\u0043\u006f\u006e\u0074\u0065\u006e\u0074\u0073"));_ebg {_bgc (_aae );}else if _gb ,_dba :=_g .GetArray (_dc .Get ("\u0043\u006f\u006e\u0074\u0065\u006e\u0074\u0073"));_dba {for _ ,_df :=range _gb .Elements (){if _dcg ,_cea :=_g .GetStream (_df );
|
|
|
|
_cea {_bgc (_dcg );};};};};case *_g .PdfObjectStream :if _aab ,_bge :=_g .GetName (_bb .Get ("\u0054\u0079\u0070\u0065"));!_bge ||_aab .String ()!="\u0058O\u0062\u006a\u0065\u0063\u0074"{continue ;};if _ebb ,_gff :=_g .GetName (_bb .Get ("\u0053u\u0062\u0074\u0079\u0070\u0065"));
|
|
|
|
!_gff ||_ebb .String ()!="\u0046\u006f\u0072\u006d"{continue ;};_bgc (_bb );};};for _ ,_fa :=range _adc {_ef =_acg (_fa );if _ef !=nil {return nil ,_ef ;};};return objects ,nil ;};
|
2021-04-23 20:28:14 +00:00
|
|
|
|
|
|
|
// 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 ;
|
2021-05-11 00:01:27 +00:00
|
|
|
};func _cgg (_daag *_dd .Image ,_dbbe float64 )(*_dd .Image ,error ){_bdda ,_aaea :=_daag .ToGoImage ();if _aaea !=nil {return nil ,_aaea ;};var _dacg _b .Image ;_cecb ,_fdgc :=_bdda .(*_b .Monochrome );if _fdgc {if _aaea =_cecb .ResolveDecode ();_aaea !=nil {return nil ,_aaea ;
|
|
|
|
};_dacg ,_aaea =_cecb .Scale (_dbbe );if _aaea !=nil {return nil ,_aaea ;};}else {_gabg :=int (_ag .RoundToEven (float64 (_daag .Width )*_dbbe ));_ccec :=int (_ag .RoundToEven (float64 (_daag .Height )*_dbbe ));_dacg ,_aaea =_b .NewImage (_gabg ,_ccec ,int (_daag .BitsPerComponent ),_daag .ColorComponents ,nil ,nil ,nil );
|
|
|
|
if _aaea !=nil {return nil ,_aaea ;};_a .CatmullRom .Scale (_dacg ,_dacg .Bounds (),_bdda ,_bdda .Bounds (),_a .Over ,&_a .Options {});};_bca :=_dacg .Base ();_bcgd :=&_dd .Image {Width :int64 (_bca .Width ),Height :int64 (_bca .Height ),BitsPerComponent :int64 (_bca .BitsPerComponent ),ColorComponents :_bca .ColorComponents ,Data :_bca .Data };
|
|
|
|
_bcgd .SetDecode (_bca .Decode );_bcgd .SetAlpha (_bca .Alpha );return _bcgd ,nil ;};
|
2020-08-27 21:45:09 +00:00
|
|
|
|
2021-05-11 00:01:27 +00:00
|
|
|
// CombineDuplicateStreams combines duplicated streams by its data hash.
|
|
|
|
// It implements interface model.Optimizer.
|
|
|
|
type CombineDuplicateStreams struct{};func _egbd (_fbff []_g .PdfObject )objectStructure {_ffb :=objectStructure {};_afbf :=false ;for _ ,_dcdc :=range _fbff {switch _ade :=_dcdc .(type ){case *_g .PdfIndirectObject :_fcd ,_geab :=_g .GetDict (_ade );if !_geab {continue ;
|
|
|
|
};_ffa ,_geab :=_g .GetName (_fcd .Get ("\u0054\u0079\u0070\u0065"));if !_geab {continue ;};switch _ffa .String (){case "\u0043a\u0074\u0061\u006c\u006f\u0067":_ffb ._dcge =_fcd ;_afbf =true ;};};if _afbf {break ;};};if !_afbf {return _ffb ;};_bcc ,_effb :=_g .GetDict (_ffb ._dcge .Get ("\u0050\u0061\u0067e\u0073"));
|
|
|
|
if !_effb {return _ffb ;};_ffb ._cdcc =_bcc ;_ffgb ,_effb :=_g .GetArray (_bcc .Get ("\u004b\u0069\u0064\u0073"));if !_effb {return _ffb ;};for _ ,_cbgc :=range _ffgb .Elements (){_gfde ,_dec :=_g .GetIndirect (_cbgc );if !_dec {break ;};_ffb ._eade =append (_ffb ._eade ,_gfde );
|
|
|
|
};return _ffb ;};func _ecdb (_gfga []_g .PdfObject )[]*imageInfo {_dab :=_g .PdfObjectName ("\u0053u\u0062\u0074\u0079\u0070\u0065");_gda :=make (map[*_g .PdfObjectStream ]struct{});var _ccdf error ;var _eaa []*imageInfo ;for _ ,_bgae :=range _gfga {_eef ,_aaf :=_g .GetStream (_bgae );
|
|
|
|
if !_aaf {continue ;};if _ ,_dge :=_gda [_eef ];_dge {continue ;};_gda [_eef ]=struct{}{};_bdcb :=_eef .PdfObjectDictionary .Get (_dab );_cabg ,_aaf :=_g .GetName (_bdcb );if !_aaf ||string (*_cabg )!="\u0049\u006d\u0061g\u0065"{continue ;};_bff :=&imageInfo {BitsPerComponent :8,Stream :_eef };
|
|
|
|
if _bff .ColorSpace ,_ccdf =_dd .DetermineColorspaceNameFromPdfObject (_eef .PdfObjectDictionary .Get ("\u0043\u006f\u006c\u006f\u0072\u0053\u0070\u0061\u0063\u0065"));_ccdf !=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",_ccdf );
|
|
|
|
continue ;};if _adb ,_gcda :=_g .GetIntVal (_eef .PdfObjectDictionary .Get ("\u0042\u0069t\u0073\u0050\u0065r\u0043\u006f\u006d\u0070\u006f\u006e\u0065\u006e\u0074"));_gcda {_bff .BitsPerComponent =_adb ;};if _fdag ,_adg :=_g .GetIntVal (_eef .PdfObjectDictionary .Get ("\u0057\u0069\u0064t\u0068"));
|
|
|
|
_adg {_bff .Width =_fdag ;};if _dfg ,_eegf :=_g .GetIntVal (_eef .PdfObjectDictionary .Get ("\u0048\u0065\u0069\u0067\u0068\u0074"));_eegf {_bff .Height =_dfg ;};switch _bff .ColorSpace {case "\u0044e\u0076\u0069\u0063\u0065\u0052\u0047B":_bff .ColorComponents =3;
|
|
|
|
case "\u0044\u0065\u0076\u0069\u0063\u0065\u0047\u0072\u0061\u0079":_bff .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",_bff .ColorSpace );
|
|
|
|
continue ;};_eaa =append (_eaa ,_bff );};return _eaa ;};func _gcd (_dcf *_g .PdfObjectStream ,_bbf []rune ,_eba []_eg .GlyphIndex )error {_dcf ,_ecd :=_g .GetStream (_dcf );if !_ecd {_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");};_fce ,_efe :=_g .DecodeStream (_dcf );if _efe !=nil {_e .Log .Debug ("\u0044\u0065c\u006f\u0064\u0065 \u0065\u0072\u0072\u006f\u0072\u003a\u0020\u0025\u0076",_efe );
|
|
|
|
return _efe ;};_fceb ,_efe :=_eg .Parse (_ba .NewReader (_fce ));if _efe !=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 (_dcf .Stream ));
|
|
|
|
return _efe ;};_cdg :=_eba ;if len (_bbf )> 0{_dcag :=_fceb .LookupRunes (_bbf );_cdg =append (_cdg ,_dcag ...);};_fceb ,_efe =_fceb .SubsetKeepIndices (_cdg );if _efe !=nil {_e .Log .Debug ("\u0045R\u0052\u004f\u0052\u0020s\u0075\u0062\u0073\u0065\u0074t\u0069n\u0067 \u0066\u006f\u006e\u0074\u003a\u0020\u0025v",_efe );
|
|
|
|
return _efe ;};var _ccd _ba .Buffer ;_efe =_fceb .Write (&_ccd );if _efe !=nil {_e .Log .Debug ("\u0045\u0052\u0052\u004fR \u0057\u0072\u0069\u0074\u0069\u006e\u0067\u0020\u0066\u006f\u006e\u0074\u003a\u0020%\u0076",_efe );return _efe ;};if _ccd .Len ()> len (_fce ){_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 ;};_fde ,_efe :=_g .MakeStream (_ccd .Bytes (),_g .NewFlateEncoder ());if _efe !=nil {_e .Log .Debug ("\u0045\u0052\u0052\u004fR \u0057\u0072\u0069\u0074\u0069\u006e\u0067\u0020\u0066\u006f\u006e\u0074\u003a\u0020%\u0076",_efe );return _efe ;
|
|
|
|
};*_dcf =*_fde ;_dcf .Set ("\u004ce\u006e\u0067\u0074\u0068\u0031",_g .MakeInteger (int64 (_ccd .Len ())));return nil ;};
|
2021-03-23 23:12:52 +00:00
|
|
|
|
2021-05-11 00:01:27 +00:00
|
|
|
// CombineDuplicateDirectObjects combines duplicated direct objects by its data hash.
|
|
|
|
// It implements interface model.Optimizer.
|
|
|
|
type CombineDuplicateDirectObjects struct{};
|
|
|
|
|
|
|
|
// Append appends optimizers to the chain.
|
|
|
|
func (_af *Chain )Append (optimizers ..._dd .Optimizer ){_af ._ed =append (_af ._ed ,optimizers ...)};
|
|
|
|
|
|
|
|
// Chain allows to use sequence of optimizers.
|
|
|
|
// It implements interface model.Optimizer.
|
|
|
|
type Chain struct{_ed []_dd .Optimizer };
|
2021-04-17 13:46:54 +00:00
|
|
|
|
|
|
|
// 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.
|
2021-05-11 00:01:27 +00:00
|
|
|
type CleanContentstream struct{};func _faef (_ebge _g .PdfObject )[]content {if _ebge ==nil {return nil ;};_gbe ,_fea :=_g .GetArray (_ebge );if !_fea {_e .Log .Debug ("\u0041\u006e\u006e\u006fts\u0020\u006e\u006f\u0074\u0020\u0061\u006e\u0020\u0061\u0072\u0072\u0061\u0079");
|
|
|
|
return nil ;};var _bc []content ;for _ ,_be :=range _gbe .Elements (){_aga ,_faee :=_g .GetDict (_be );if !_faee {_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 ;};_gd ,_faee :=_g .GetDict (_aga .Get ("\u0041\u0050"));if !_faee {_e .Log .Debug ("\u004e\u006f\u0020\u0041P \u0065\u006e\u0074\u0072\u0079\u0020\u002d\u0020\u0073\u006b\u0069\u0070\u0070\u0069n\u0067");continue ;};_dfb :=_g .TraceToDirectObject (_gd .Get ("\u004e"));
|
|
|
|
if _dfb ==nil {_e .Log .Debug ("N\u006f\u0020\u004e\u0020en\u0074r\u0079\u0020\u002d\u0020\u0073k\u0069\u0070\u0070\u0069\u006e\u0067");continue ;};var _cec *_g .PdfObjectStream ;switch _cdb :=_dfb .(type ){case *_g .PdfObjectDictionary :_dce ,_gfb :=_g .GetName (_aga .Get ("\u0041\u0053"));
|
|
|
|
if !_gfb {_e .Log .Debug ("\u004e\u006f\u0020\u0041S \u0065\u006e\u0074\u0072\u0079\u0020\u002d\u0020\u0073\u006b\u0069\u0070\u0070\u0069n\u0067");continue ;};_cec ,_gfb =_g .GetStream (_cdb .Get (*_dce ));if !_gfb {_e .Log .Debug ("\u0046o\u0072\u006d\u0020\u006eo\u0074\u0020\u0066\u006f\u0075n\u0064 \u002d \u0073\u006b\u0069\u0070\u0070\u0069\u006eg");
|
|
|
|
continue ;};case *_g .PdfObjectStream :_cec =_cdb ;};if _cec ==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 ;};_fba ,_ecb :=_dd .NewXObjectFormFromStream (_cec );if _ecb !=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",_ecb );
|
|
|
|
continue ;};_fbf ,_ecb :=_fba .GetContentStream ();if _ecb !=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",_ecb );continue ;};_bc =append (_bc ,content {_fae :string (_fbf ),_bdf :_fba .Resources });
|
|
|
|
};return _bc ;};
|
2020-09-28 23:18:17 +00:00
|
|
|
|
2021-03-23 23:12:52 +00:00
|
|
|
// Optimize optimizes PDF objects to decrease PDF size.
|
2021-05-11 00:01:27 +00:00
|
|
|
func (_cgf *CombineIdenticalIndirectObjects )Optimize (objects []_g .PdfObject )(_eee []_g .PdfObject ,_eac error ){_bfd (objects );_egd :=make (map[_g .PdfObject ]_g .PdfObject );_dbc :=make (map[_g .PdfObject ]struct{});_afc :=make (map[string ][]*_g .PdfIndirectObject );
|
|
|
|
for _ ,_efg :=range objects {_fcae ,_abd :=_efg .(*_g .PdfIndirectObject );if !_abd {continue ;};if _cda ,_cf :=_fcae .PdfObject .(*_g .PdfObjectDictionary );_cf {if _bcd ,_fbc :=_cda .Get ("\u0054\u0079\u0070\u0065").(*_g .PdfObjectName );_fbc &&*_bcd =="\u0050\u0061\u0067\u0065"{continue ;
|
|
|
|
};_ccf :=_d .New ();_ccf .Write ([]byte (_cda .WriteString ()));_efac :=string (_ccf .Sum (nil ));_afc [_efac ]=append (_afc [_efac ],_fcae );};};for _ ,_faed :=range _afc {if len (_faed )< 2{continue ;};_dga :=_faed [0];for _eeg :=1;_eeg < len (_faed );
|
|
|
|
_eeg ++{_fcec :=_faed [_eeg ];_egd [_fcec ]=_dga ;_dbc [_fcec ]=struct{}{};};};_eee =make ([]_g .PdfObject ,0,len (objects )-len (_dbc ));for _ ,_dcda :=range objects {if _ ,_bddb :=_dbc [_dcda ];_bddb {continue ;};_eee =append (_eee ,_dcda );};_fbae (_eee ,_egd );
|
|
|
|
return _eee ,nil ;};
|
2020-12-06 13:03:03 +00:00
|
|
|
|
2021-05-11 00:01:27 +00:00
|
|
|
// Optimize optimizes PDF objects to decrease PDF size.
|
|
|
|
func (_ggba *ImagePPI )Optimize (objects []_g .PdfObject )(_gae []_g .PdfObject ,_aec error ){if _ggba .ImageUpperPPI <=0{return objects ,nil ;};_dfa :=_ecdb (objects );if len (_dfa )==0{return objects ,nil ;};_bace :=make (map[_g .PdfObject ]struct{});
|
|
|
|
for _ ,_bcda :=range _dfa {_cbdb :=_bcda .Stream .PdfObjectDictionary .Get (_g .PdfObjectName ("\u0053\u004d\u0061s\u006b"));_bace [_cbdb ]=struct{}{};};_fefe :=make (map[*_g .PdfObjectStream ]*imageInfo );for _ ,_gcgg :=range _dfa {_fefe [_gcgg .Stream ]=_gcgg ;
|
|
|
|
};var _afd *_g .PdfObjectDictionary ;for _ ,_gac :=range objects {if _egba ,_ggfa :=_g .GetDict (_gac );_afd ==nil &&_ggfa {if _eec ,_deac :=_g .GetName (_egba .Get (_g .PdfObjectName ("\u0054\u0079\u0070\u0065")));_deac &&*_eec =="\u0043a\u0074\u0061\u006c\u006f\u0067"{_afd =_egba ;
|
|
|
|
};};};if _afd ==nil {return objects ,nil ;};_dadd ,_adbg :=_g .GetDict (_afd .Get (_g .PdfObjectName ("\u0050\u0061\u0067e\u0073")));if !_adbg {return objects ,nil ;};_baac ,_bcgdb :=_g .GetArray (_dadd .Get (_g .PdfObjectName ("\u004b\u0069\u0064\u0073")));
|
|
|
|
if !_bcgdb {return objects ,nil ;};_dbcc :=make (map[string ]*imageInfo );for _ ,_efgb :=range _baac .Elements (){_fab ,_dfcb :=_g .GetDict (_efgb );if !_dfcb {continue ;};_ggc ,_cbgf :=_g .GetArray (_fab .Get ("\u0043\u006f\u006e\u0074\u0065\u006e\u0074\u0073"));
|
|
|
|
if !_cbgf {continue ;};_bdga ,_fdaa :=_g .GetDict (_fab .Get ("\u0052e\u0073\u006f\u0075\u0072\u0063\u0065s"));if !_fdaa {continue ;};_cfc ,_feag :=_g .GetDict (_bdga .Get ("\u0058O\u0062\u006a\u0065\u0063\u0074"));if !_feag {continue ;};_dfga :=_cfc .Keys ();
|
|
|
|
for _ ,_ffg :=range _dfga {if _bea ,_ddba :=_g .GetStream (_cfc .Get (_ffg ));_ddba {if _aecf ,_cbea :=_fefe [_bea ];_cbea {_dbcc [string (_ffg )]=_aecf ;};};};for _ ,_cgca :=range _ggc .Elements (){if _ecgf ,_eage :=_g .GetStream (_cgca );_eage {_ccb ,_fcg :=_g .NewEncoderFromStream (_ecgf );
|
|
|
|
if _fcg !=nil {return nil ,_fcg ;};_cfaf ,_fcg :=_ccb .DecodeStream (_ecgf );if _fcg !=nil {return nil ,_fcg ;};_bdb :=_fb .NewContentStreamParser (string (_cfaf ));_daga ,_fcg :=_bdb .Parse ();if _fcg !=nil {return nil ,_fcg ;};_afae ,_abe :=1.0,1.0;for _ ,_dgaf :=range *_daga {if _dgaf .Operand =="\u0051"{_afae ,_abe =1.0,1.0;
|
|
|
|
};if _dgaf .Operand =="\u0063\u006d"&&len (_dgaf .Params )==6{if _dace ,_bgg :=_g .GetFloatVal (_dgaf .Params [0]);_bgg {_afae =_afae *_dace ;};if _fafg ,_acf :=_g .GetFloatVal (_dgaf .Params [3]);_acf {_abe =_abe *_fafg ;};if _gcga ,_bded :=_g .GetIntVal (_dgaf .Params [0]);
|
|
|
|
_bded {_afae =_afae *float64 (_gcga );};if _bae ,_bcde :=_g .GetIntVal (_dgaf .Params [3]);_bcde {_abe =_abe *float64 (_bae );};};if _dgaf .Operand =="\u0044\u006f"&&len (_dgaf .Params )==1{_aee ,_gbb :=_g .GetName (_dgaf .Params [0]);if !_gbb {continue ;
|
|
|
|
};if _bebf ,_feb :=_dbcc [string (*_aee )];_feb {_eegd ,_adcc :=_afae /72.0,_abe /72.0;_gfbc ,_geef :=float64 (_bebf .Width )/_eegd ,float64 (_bebf .Height )/_adcc ;if _eegd ==0||_adcc ==0{_gfbc =72.0;_geef =72.0;};_bebf .PPI =_ag .Max (_bebf .PPI ,_gfbc );
|
|
|
|
_bebf .PPI =_ag .Max (_bebf .PPI ,_geef );};};};};};};for _ ,_bef :=range _dfa {if _ ,_ged :=_bace [_bef .Stream ];_ged {continue ;};if _bef .PPI <=_ggba .ImageUpperPPI {continue ;};_afca ,_agbb :=_dd .NewXObjectImageFromStream (_bef .Stream );if _agbb !=nil {return nil ,_agbb ;
|
|
|
|
};var _acc imageModifications ;_acc .Scale =_ggba .ImageUpperPPI /_bef .PPI ;if _bef .BitsPerComponent ==1&&_bef .ColorComponents ==1{_gdc :=_ag .Round (_bef .PPI /_ggba .ImageUpperPPI );_eefc :=_b .NextPowerOf2 (uint (_gdc ));if _b .InDelta (float64 (_eefc ),1/_acc .Scale ,0.3){_acc .Scale =float64 (1)/float64 (_eefc );
|
|
|
|
};if _ ,_bgec :=_afca .Filter .(*_g .JBIG2Encoder );!_bgec {_acc .Encoding =_g .NewJBIG2Encoder ();};};if _agbb =_fbbf (_afca ,_acc );_agbb !=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",_agbb );
|
|
|
|
continue ;};_acc .Encoding =nil ;if _befe ,_ccga :=_g .GetStream (_bef .Stream .PdfObjectDictionary .Get (_g .PdfObjectName ("\u0053\u004d\u0061s\u006b")));_ccga {_cfd ,_dcae :=_dd .NewXObjectImageFromStream (_befe );if _dcae !=nil {return nil ,_dcae ;
|
|
|
|
};if _dcae =_fbbf (_cfd ,_acc );_dcae !=nil {return nil ,_dcae ;};};};return objects ,nil ;};
|
2020-09-21 01:20:10 +00:00
|
|
|
|
2021-04-17 13:46:54 +00:00
|
|
|
// Optimize optimizes PDF objects to decrease PDF size.
|
2021-05-11 00:01:27 +00:00
|
|
|
func (_gbc *Image )Optimize (objects []_g .PdfObject )(_gcc []_g .PdfObject ,_dbbd error ){if _gbc .ImageQuality <=0{return objects ,nil ;};_fddd :=_ecdb (objects );if len (_fddd )==0{return objects ,nil ;};_caab :=make (map[_g .PdfObject ]_g .PdfObject );
|
|
|
|
_fdg :=make (map[_g .PdfObject ]struct{});for _ ,_dddf :=range _fddd {_agdg :=_dddf .Stream .PdfObjectDictionary .Get (_g .PdfObjectName ("\u0053\u004d\u0061s\u006b"));_fdg [_agdg ]=struct{}{};};for _deb ,_eggc :=range _fddd {_feae :=_eggc .Stream ;if _ ,_dda :=_fdg [_feae ];
|
|
|
|
_dda {continue ;};_ddad ,_gfe :=_g .NewEncoderFromStream (_feae );if _gfe !=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 ;};_aaeg ,_gfe :=_ddad .DecodeStream (_feae );if _gfe !=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 ;};_ccg :=_g .NewDCTEncoder ();_ccg .ColorComponents =_eggc .ColorComponents ;_ccg .Quality =_gbc .ImageQuality ;_ccg .BitsPerComponent =_eggc .BitsPerComponent ;_ccg .Width =_eggc .Width ;_ccg .Height =_eggc .Height ;_cfg ,_gfe :=_ccg .EncodeBytes (_aaeg );
|
|
|
|
if _gfe !=nil {_e .Log .Debug ("\u0045R\u0052\u004f\u0052\u003a\u0020\u0025v",_gfe );return nil ,_gfe ;};var _cdcb _g .StreamEncoder ;_cdcb =_ccg ;{_ggf :=_g .NewFlateEncoder ();_beb :=_g .NewMultiEncoder ();_beb .AddEncoder (_ggf );_beb .AddEncoder (_ccg );
|
|
|
|
_ccgd ,_cgc :=_beb .EncodeBytes (_aaeg );if _cgc !=nil {return nil ,_cgc ;};if len (_ccgd )< len (_cfg ){_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 (_cfg ),len (_ccgd ),len (_feae .Stream ));
|
|
|
|
_cfg =_ccgd ;_cdcb =_beb ;};};_faf :=len (_feae .Stream );if _faf < len (_cfg ){continue ;};_gca :=&_g .PdfObjectStream {Stream :_cfg };_gca .PdfObjectReference =_feae .PdfObjectReference ;_gca .PdfObjectDictionary =_g .MakeDict ();_gca .Merge (_feae .PdfObjectDictionary );
|
|
|
|
_gca .Merge (_cdcb .MakeStreamDict ());_gca .Set ("\u004c\u0065\u006e\u0067\u0074\u0068",_g .MakeInteger (int64 (len (_cfg ))));_caab [_feae ]=_gca ;_fddd [_deb ].Stream =_gca ;};_gcc =make ([]_g .PdfObject ,len (objects ));copy (_gcc ,objects );_fbae (_gcc ,_caab );
|
|
|
|
return _gcc ,nil ;};
|
2020-12-06 13:03:03 +00:00
|
|
|
|
2021-05-11 00:01:27 +00:00
|
|
|
// Image optimizes images by rewrite images into JPEG format with quality equals to ImageQuality.
|
|
|
|
// TODO(a5i): Add support for inline images.
|
2021-03-23 23:12:52 +00:00
|
|
|
// It implements interface model.Optimizer.
|
2021-05-11 00:01:27 +00:00
|
|
|
type Image struct{ImageQuality int ;};
|
2021-04-23 20:28:14 +00:00
|
|
|
|
|
|
|
// Optimize optimizes PDF objects to decrease PDF size.
|
2021-05-11 00:01:27 +00:00
|
|
|
func (_cdbe *CompressStreams )Optimize (objects []_g .PdfObject )(_gde []_g .PdfObject ,_add error ){_gde =make ([]_g .PdfObject ,len (objects ));copy (_gde ,objects );for _ ,_ebgf :=range objects {_agdd ,_cgfg :=_g .GetStream (_ebgf );if !_cgfg {continue ;
|
|
|
|
};if _caadg :=_agdd .Get ("\u0046\u0069\u006c\u0074\u0065\u0072");_caadg !=nil {if _ ,_abb :=_g .GetName (_caadg );_abb {continue ;};if _fac ,_aaaf :=_g .GetArray (_caadg );_aaaf &&_fac .Len ()> 0{continue ;};};_cfa :=_g .NewFlateEncoder ();var _ecg []byte ;
|
|
|
|
_ecg ,_add =_cfa .EncodeBytes (_agdd .Stream );if _add !=nil {return _gde ,_add ;};_eab :=_cfa .MakeStreamDict ();if len (_ecg )+len (_eab .WriteString ())< len (_agdd .Stream ){_agdd .Stream =_ecg ;_agdd .PdfObjectDictionary .Merge (_eab );_agdd .PdfObjectDictionary .Set ("\u004c\u0065\u006e\u0067\u0074\u0068",_g .MakeInteger (int64 (len (_agdd .Stream ))));
|
|
|
|
};};return _gde ,nil ;};type imageInfo struct{ColorSpace _g .PdfObjectName ;BitsPerComponent int ;ColorComponents int ;Width int ;Height int ;Stream *_g .PdfObjectStream ;PPI float64 ;};type content struct{_fae string ;_bdf *_dd .PdfPageResources ;};
|
2021-04-23 20:28:14 +00:00
|
|
|
|
|
|
|
// Optimize optimizes PDF objects to decrease PDF size.
|
2021-05-11 00:01:27 +00:00
|
|
|
func (_dgc *CombineDuplicateDirectObjects )Optimize (objects []_g .PdfObject )(_eca []_g .PdfObject ,_gffg error ){_bfd (objects );_dddg :=make (map[string ][]*_g .PdfObjectDictionary );var _dag func (_fbbc *_g .PdfObjectDictionary );_dag =func (_fcc *_g .PdfObjectDictionary ){for _ ,_gab :=range _fcc .Keys (){_edd :=_fcc .Get (_gab );
|
|
|
|
if _ddbf ,_feee :=_edd .(*_g .PdfObjectDictionary );_feee {_ace :=_d .New ();_ace .Write ([]byte (_ddbf .WriteString ()));_bdc :=string (_ace .Sum (nil ));_dddg [_bdc ]=append (_dddg [_bdc ],_ddbf );_dag (_ddbf );};};};for _ ,_aed :=range objects {_eag ,_bde :=_aed .(*_g .PdfIndirectObject );
|
|
|
|
if !_bde {continue ;};if _ffc ,_ded :=_eag .PdfObject .(*_g .PdfObjectDictionary );_ded {_dag (_ffc );};};_eed :=make ([]_g .PdfObject ,0,len (_dddg ));_eaf :=make (map[_g .PdfObject ]_g .PdfObject );for _ ,_deg :=range _dddg {if len (_deg )< 2{continue ;
|
|
|
|
};_cbg :=_g .MakeDict ();_cbg .Merge (_deg [0]);_efa :=_g .MakeIndirectObject (_cbg );_eed =append (_eed ,_efa );for _bbee :=0;_bbee < len (_deg );_bbee ++{_bcg :=_deg [_bbee ];_eaf [_bcg ]=_efa ;};};_eca =make ([]_g .PdfObject ,len (objects ));copy (_eca ,objects );
|
|
|
|
_eca =append (_eed ,_eca ...);_fbae (_eca ,_eaf );return _eca ,nil ;};
|
2020-10-05 19:28:24 +00:00
|
|
|
|
2021-05-11 00:01:27 +00:00
|
|
|
// ObjectStreams groups PDF objects to object streams.
|
2021-02-22 02:29:48 +00:00
|
|
|
// It implements interface model.Optimizer.
|
2021-05-11 00:01:27 +00:00
|
|
|
type ObjectStreams struct{};func _de (_fe []_g .PdfObject )(_ea map[*_g .PdfObjectStream ]struct{},_egb error ){_ea =map[*_g .PdfObjectStream ]struct{}{};_cb :=map[*_dd .PdfFont ]struct{}{};_afg :=_egbd (_fe );for _ ,_egc :=range _afg ._eade {_da ,_edg :=_g .GetDict (_egc .PdfObject );
|
|
|
|
if !_edg {continue ;};_edb ,_edg :=_g .GetDict (_da .Get ("\u0052e\u0073\u006f\u0075\u0072\u0063\u0065s"));if !_edg {continue ;};_gcb ,_ :=_cgag (_da .Get ("\u0043\u006f\u006e\u0074\u0065\u006e\u0074\u0073"));_ab ,_dca :=_dd .NewPdfPageResourcesFromDict (_edb );
|
|
|
|
if _dca !=nil {return nil ,_dca ;};_age :=[]content {{_fae :_gcb ,_bdf :_ab }};_bad :=_faef (_da .Get ("\u0041\u006e\u006e\u006f\u0074\u0073"));if _bad !=nil {_age =append (_age ,_bad ...);};for _ ,_dcb :=range _age {_cdc ,_bdg :=_gg .NewFromContents (_dcb ._fae ,_dcb ._bdf );
|
|
|
|
if _bdg !=nil {return nil ,_bdg ;};_aea ,_ ,_ ,_bdg :=_cdc .ExtractPageText ();if _bdg !=nil {return nil ,_bdg ;};for _ ,_ggb :=range _aea .Marks ().Elements (){if _ggb .Font ==nil {continue ;};if _ ,_agd :=_cb [_ggb .Font ];!_agd {_cb [_ggb .Font ]=struct{}{};
|
|
|
|
};};};};_dfc :=map[*_g .PdfObjectStream ][]*_dd .PdfFont {};for _abf :=range _cb {_bac :=_abf .FontDescriptor ();if _bac ==nil ||_bac .FontFile2 ==nil {continue ;};_ff ,_gfdg :=_g .GetStream (_bac .FontFile2 );if !_gfdg {continue ;};_dfc [_ff ]=append (_dfc [_ff ],_abf );
|
|
|
|
};for _cab :=range _dfc {var _cbd []rune ;var _fd []_eg .GlyphIndex ;for _ ,_baa :=range _dfc [_cab ]{switch _gcg :=_baa .Encoder ().(type ){case *_c .IdentityEncoder :_fff :=_gcg .RegisteredRunes ();_egg :=make ([]_eg .GlyphIndex ,len (_fff ));for _dg ,_ec :=range _fff {_egg [_dg ]=_eg .GlyphIndex (_ec );
|
|
|
|
};_fd =append (_fd ,_egg ...);case *_c .TrueTypeFontEncoder :_faa :=_gcg .RegisteredRunes ();_cbd =append (_cbd ,_faa ...);case _c .SimpleEncoder :_dbb :=_gcg .Charcodes ();for _ ,_gfc :=range _dbb {_ffe ,_dbbg :=_gcg .CharcodeToRune (_gfc );if !_dbbg {_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",_gfc );
|
|
|
|
continue ;};_cbd =append (_cbd ,_ffe );};};};_egb =_gcd (_cab ,_cbd ,_fd );if _egb !=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",_egb );
|
|
|
|
return nil ,_egb ;};_ea [_cab ]=struct{}{};};return _ea ,nil ;};type imageModifications struct{Scale float64 ;Encoding _g .StreamEncoder ;};
|
2021-02-22 02:29:48 +00:00
|
|
|
|
2021-04-23 20:28:14 +00:00
|
|
|
// CombineIdenticalIndirectObjects combines identical indirect objects.
|
|
|
|
// It implements interface model.Optimizer.
|
|
|
|
type CombineIdenticalIndirectObjects struct{};
|
2021-01-26 01:31:56 +00:00
|
|
|
|
2021-05-11 00:01:27 +00:00
|
|
|
// 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.
|
2021-03-23 23:12:52 +00:00
|
|
|
// It implements interface model.Optimizer.
|
2021-05-11 00:01:27 +00:00
|
|
|
type ImagePPI struct{ImageUpperPPI float64 ;};func _acg (_bd *_g .PdfObjectStream )error {_fc ,_gc :=_g .DecodeStream (_bd );if _gc !=nil {return _gc ;};_gfg :=_fb .NewContentStreamParser (string (_fc ));_ce ,_gc :=_gfg .Parse ();if _gc !=nil {return _gc ;
|
|
|
|
};_ce =_cge (_ce );_aa :=_ce .Bytes ();if len (_aa )>=len (_fc ){return nil ;};_ggg ,_gc :=_g .MakeStream (_ce .Bytes (),_g .NewFlateEncoder ());if _gc !=nil {return _gc ;};_bd .Stream =_ggg .Stream ;_bd .Merge (_ggg .PdfObjectDictionary );return nil ;
|
|
|
|
};func _cgag (_efada _g .PdfObject )(_bggg string ,_faba []_g .PdfObject ){var _cfge _ba .Buffer ;switch _gge :=_efada .(type ){case *_g .PdfIndirectObject :_faba =append (_faba ,_gge );_efada =_gge .PdfObject ;};switch _dadf :=_efada .(type ){case *_g .PdfObjectStream :if _ccee ,_cabc :=_g .DecodeStream (_dadf );
|
|
|
|
_cabc ==nil {_cfge .Write (_ccee );_faba =append (_faba ,_dadf );};case *_g .PdfObjectArray :for _ ,_dabb :=range _dadf .Elements (){switch _aegb :=_dabb .(type ){case *_g .PdfObjectStream :if _cfb ,_ebf :=_g .DecodeStream (_aegb );_ebf ==nil {_cfge .Write (_cfb );
|
|
|
|
_faba =append (_faba ,_aegb );};};};};return _cfge .String (),_faba ;};func _fbae (_bdec []_g .PdfObject ,_efaf map[_g .PdfObject ]_g .PdfObject ){if len (_efaf )==0{return ;};for _gdg ,_bab :=range _bdec {if _gga ,_fccg :=_efaf [_bab ];_fccg {_bdec [_gdg ]=_gga ;
|
|
|
|
continue ;};_efaf [_bab ]=_bab ;switch _cgd :=_bab .(type ){case *_g .PdfObjectArray :_gbg :=make ([]_g .PdfObject ,_cgd .Len ());copy (_gbg ,_cgd .Elements ());_fbae (_gbg ,_efaf );for _cee ,_cbeab :=range _gbg {_cgd .Set (_cee ,_cbeab );};case *_g .PdfObjectStreams :_fbae (_cgd .Elements (),_efaf );
|
|
|
|
case *_g .PdfObjectStream :_cac :=[]_g .PdfObject {_cgd .PdfObjectDictionary };_fbae (_cac ,_efaf );_cgd .PdfObjectDictionary =_cac [0].(*_g .PdfObjectDictionary );case *_g .PdfObjectDictionary :_aef :=_cgd .Keys ();_ddc :=make ([]_g .PdfObject ,len (_aef ));
|
|
|
|
for _abbd ,_gfeg :=range _aef {_ddc [_abbd ]=_cgd .Get (_gfeg );};_fbae (_ddc ,_efaf );for _gea ,_ceee :=range _aef {_cgd .Set (_ceee ,_ddc [_gea ]);};case *_g .PdfIndirectObject :_dbe :=[]_g .PdfObject {_cgd .PdfObject };_fbae (_dbe ,_efaf );_cgd .PdfObject =_dbe [0];
|
|
|
|
};};};
|
2021-04-17 13:46:54 +00:00
|
|
|
|
2021-04-23 20:28:14 +00:00
|
|
|
// New creates a optimizers chain from options.
|
2021-05-11 00:01:27 +00:00
|
|
|
func New (options Options )*Chain {_abg :=new (Chain );if options .CleanFonts ||options .SubsetFonts {_abg .Append (&CleanFonts {Subset :options .SubsetFonts });};if options .CleanContentstream {_abg .Append (new (CleanContentstream ));};if options .ImageUpperPPI > 0{_efad :=new (ImagePPI );
|
|
|
|
_efad .ImageUpperPPI =options .ImageUpperPPI ;_abg .Append (_efad );};if options .ImageQuality > 0{_beeg :=new (Image );_beeg .ImageQuality =options .ImageQuality ;_abg .Append (_beeg );};if options .CombineDuplicateDirectObjects {_abg .Append (new (CombineDuplicateDirectObjects ));
|
|
|
|
};if options .CombineDuplicateStreams {_abg .Append (new (CombineDuplicateStreams ));};if options .CombineIdenticalIndirectObjects {_abg .Append (new (CombineIdenticalIndirectObjects ));};if options .UseObjectStreams {_abg .Append (new (ObjectStreams ));
|
|
|
|
};if options .CompressStreams {_abg .Append (new (CompressStreams ));};return _abg ;};func _fbbf (_efd *_dd .XObjectImage ,_agc imageModifications )error {_ebdg ,_gdeg :=_efd .ToImage ();if _gdeg !=nil {return _gdeg ;};if _agc .Scale !=0{_ebdg ,_gdeg =_cgg (_ebdg ,_agc .Scale );
|
|
|
|
if _gdeg !=nil {return _gdeg ;};};if _agc .Encoding !=nil {_efd .Filter =_agc .Encoding ;};_dege :=_g .MakeDict ();_dege .Set ("\u0051u\u0061\u006c\u0069\u0074\u0079",_g .MakeInteger (100));_dege .Set ("\u0050r\u0065\u0064\u0069\u0063\u0074\u006fr",_g .MakeInteger (1));
|
|
|
|
_efd .Decode =nil ;if _gdeg =_efd .SetImage (_ebdg ,nil );_gdeg !=nil {return _gdeg ;};_efd .ToPdfObject ();return nil ;};
|