github.com/linuxboot/fiano@v1.2.0/pkg/compression/lzma.go (about) 1 // Copyright 2018 the LinuxBoot Authors. All rights reserved 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package compression 6 7 import ( 8 "bytes" 9 "io" 10 11 "github.com/ulikunitz/xz/lzma" 12 ) 13 14 // Mapping from compression level to dictionary size. 15 var lzmaDictCapExps = []uint{18, 20, 21, 22, 22, 23, 23, 24, 25, 26} 16 var compressionLevel = 7 17 18 // LZMA implements Compressor and uses a Go-based implementation. 19 type LZMA struct{} 20 21 // Name returns the type of compression employed. 22 func (c *LZMA) Name() string { 23 return "LZMA" 24 } 25 26 // Decode decodes a byte slice of LZMA data. 27 func (c *LZMA) Decode(encodedData []byte) ([]byte, error) { 28 r, err := lzma.NewReader(bytes.NewBuffer(encodedData)) 29 if err != nil { 30 return nil, err 31 } 32 return io.ReadAll(r) 33 } 34 35 // Encode encodes a byte slice with LZMA. 36 func (c *LZMA) Encode(decodedData []byte) ([]byte, error) { 37 // These options are supported by the xz's LZMA command and EDK2's LZMA. 38 wc := lzma.WriterConfig{ 39 SizeInHeader: true, 40 Size: int64(len(decodedData)), 41 EOSMarker: false, 42 Properties: &lzma.Properties{LC: 3, LP: 0, PB: 2}, 43 DictCap: 1 << lzmaDictCapExps[compressionLevel], 44 } 45 if err := wc.Verify(); err != nil { 46 return nil, err 47 } 48 buf := &bytes.Buffer{} 49 w, err := wc.NewWriter(buf) 50 if err != nil { 51 return nil, err 52 } 53 if _, err := io.Copy(w, bytes.NewBuffer(decodedData)); err != nil { 54 return nil, err 55 } 56 if err := w.Close(); err != nil { 57 return nil, err 58 } 59 return buf.Bytes(), nil 60 }