Lorenz Brun | 378a445 | 2021-01-26 13:47:41 +0100 | [diff] [blame] | 1 | // Copyright 2020 The Monogon Project Authors. |
| 2 | // |
| 3 | // SPDX-License-Identifier: Apache-2.0 |
| 4 | // |
| 5 | // Licensed under the Apache License, Version 2.0 (the "License"); |
| 6 | // you may not use this file except in compliance with the License. |
| 7 | // You may obtain a copy of the License at |
| 8 | // |
| 9 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | // |
| 11 | // Unless required by applicable law or agreed to in writing, software |
| 12 | // distributed under the License is distributed on an "AS IS" BASIS, |
| 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 14 | // See the License for the specific language governing permissions and |
| 15 | // limitations under the License. |
| 16 | |
| 17 | package erofs |
| 18 | |
| 19 | // This file contains compression-related functions. |
| 20 | // TODO(lorenz): Fully implement compression. These are currently unused. |
| 21 | |
| 22 | import "encoding/binary" |
| 23 | |
Serge Bazanski | 216fe7b | 2021-05-21 18:36:16 +0200 | [diff] [blame^] | 24 | // mapHeader is a legacy but still-used advisory structure at the start of a |
| 25 | // compressed VLE block. It contains constant values as annotated. |
Lorenz Brun | 378a445 | 2021-01-26 13:47:41 +0100 | [diff] [blame] | 26 | type mapHeader struct { |
| 27 | Reserved uint32 // 0 |
| 28 | Advise uint16 // 1 |
| 29 | AlgorithmType uint8 // 0 |
| 30 | ClusterBits uint8 // 0 |
| 31 | } |
| 32 | |
| 33 | // encodeSmallVLEBlock encodes two VLE extents into a 8 byte block. |
| 34 | func encodeSmallVLEBlock(vals [2]uint16, blkaddr uint32) [8]byte { |
| 35 | var out [8]byte |
| 36 | binary.LittleEndian.PutUint16(out[0:2], vals[0]) |
| 37 | binary.LittleEndian.PutUint16(out[2:4], vals[1]) |
| 38 | binary.LittleEndian.PutUint32(out[4:8], blkaddr) |
| 39 | return out |
| 40 | } |
| 41 | |
| 42 | // encodeBigVLEBlock encodes 16 VLE extents into a 32 byte block. |
| 43 | func encodeBigVLEBlock(vals [16]uint16, blkaddr uint32) [32]byte { |
| 44 | var out [32]byte |
| 45 | for i, val := range vals { |
| 46 | if val > 1<<14 { |
| 47 | panic("value is bigger than 14 bits, cannot encode") |
| 48 | } |
| 49 | // Writes packed 14 bit unsigned integers |
| 50 | pos := i * 14 |
| 51 | bitStartPos := pos % 8 |
| 52 | byteStartPos := pos / 8 |
| 53 | out[byteStartPos] = out[byteStartPos]&((1<<bitStartPos)-1) | uint8(val<<bitStartPos) |
| 54 | out[byteStartPos+1] = uint8(val >> (8 - bitStartPos)) |
| 55 | out[byteStartPos+2] = uint8(val >> (16 - bitStartPos)) |
| 56 | } |
| 57 | binary.LittleEndian.PutUint32(out[28:32], blkaddr) |
| 58 | return out |
| 59 | } |