Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v5.5-rc2 332 lines 11 kB view raw
1/* 2 * FSE : Finite State Entropy decoder 3 * Copyright (C) 2013-2015, Yann Collet. 4 * 5 * BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions are 9 * met: 10 * 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * * Redistributions in binary form must reproduce the above 14 * copyright notice, this list of conditions and the following disclaimer 15 * in the documentation and/or other materials provided with the 16 * distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 * 30 * This program is free software; you can redistribute it and/or modify it under 31 * the terms of the GNU General Public License version 2 as published by the 32 * Free Software Foundation. This program is dual-licensed; you may select 33 * either version 2 of the GNU General Public License ("GPL") or BSD license 34 * ("BSD"). 35 * 36 * You can contact the author at : 37 * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy 38 */ 39 40/* ************************************************************** 41* Compiler specifics 42****************************************************************/ 43#define FORCE_INLINE static __always_inline 44 45/* ************************************************************** 46* Includes 47****************************************************************/ 48#include "bitstream.h" 49#include "fse.h" 50#include <linux/compiler.h> 51#include <linux/kernel.h> 52#include <linux/string.h> /* memcpy, memset */ 53 54/* ************************************************************** 55* Error Management 56****************************************************************/ 57#define FSE_isError ERR_isError 58#define FSE_STATIC_ASSERT(c) \ 59 { \ 60 enum { FSE_static_assert = 1 / (int)(!!(c)) }; \ 61 } /* use only *after* variable declarations */ 62 63/* check and forward error code */ 64#define CHECK_F(f) \ 65 { \ 66 size_t const e = f; \ 67 if (FSE_isError(e)) \ 68 return e; \ 69 } 70 71/* ************************************************************** 72* Templates 73****************************************************************/ 74/* 75 designed to be included 76 for type-specific functions (template emulation in C) 77 Objective is to write these functions only once, for improved maintenance 78*/ 79 80/* safety checks */ 81#ifndef FSE_FUNCTION_EXTENSION 82#error "FSE_FUNCTION_EXTENSION must be defined" 83#endif 84#ifndef FSE_FUNCTION_TYPE 85#error "FSE_FUNCTION_TYPE must be defined" 86#endif 87 88/* Function names */ 89#define FSE_CAT(X, Y) X##Y 90#define FSE_FUNCTION_NAME(X, Y) FSE_CAT(X, Y) 91#define FSE_TYPE_NAME(X, Y) FSE_CAT(X, Y) 92 93/* Function templates */ 94 95size_t FSE_buildDTable_wksp(FSE_DTable *dt, const short *normalizedCounter, unsigned maxSymbolValue, unsigned tableLog, void *workspace, size_t workspaceSize) 96{ 97 void *const tdPtr = dt + 1; /* because *dt is unsigned, 32-bits aligned on 32-bits */ 98 FSE_DECODE_TYPE *const tableDecode = (FSE_DECODE_TYPE *)(tdPtr); 99 U16 *symbolNext = (U16 *)workspace; 100 101 U32 const maxSV1 = maxSymbolValue + 1; 102 U32 const tableSize = 1 << tableLog; 103 U32 highThreshold = tableSize - 1; 104 105 /* Sanity Checks */ 106 if (workspaceSize < sizeof(U16) * (FSE_MAX_SYMBOL_VALUE + 1)) 107 return ERROR(tableLog_tooLarge); 108 if (maxSymbolValue > FSE_MAX_SYMBOL_VALUE) 109 return ERROR(maxSymbolValue_tooLarge); 110 if (tableLog > FSE_MAX_TABLELOG) 111 return ERROR(tableLog_tooLarge); 112 113 /* Init, lay down lowprob symbols */ 114 { 115 FSE_DTableHeader DTableH; 116 DTableH.tableLog = (U16)tableLog; 117 DTableH.fastMode = 1; 118 { 119 S16 const largeLimit = (S16)(1 << (tableLog - 1)); 120 U32 s; 121 for (s = 0; s < maxSV1; s++) { 122 if (normalizedCounter[s] == -1) { 123 tableDecode[highThreshold--].symbol = (FSE_FUNCTION_TYPE)s; 124 symbolNext[s] = 1; 125 } else { 126 if (normalizedCounter[s] >= largeLimit) 127 DTableH.fastMode = 0; 128 symbolNext[s] = normalizedCounter[s]; 129 } 130 } 131 } 132 memcpy(dt, &DTableH, sizeof(DTableH)); 133 } 134 135 /* Spread symbols */ 136 { 137 U32 const tableMask = tableSize - 1; 138 U32 const step = FSE_TABLESTEP(tableSize); 139 U32 s, position = 0; 140 for (s = 0; s < maxSV1; s++) { 141 int i; 142 for (i = 0; i < normalizedCounter[s]; i++) { 143 tableDecode[position].symbol = (FSE_FUNCTION_TYPE)s; 144 position = (position + step) & tableMask; 145 while (position > highThreshold) 146 position = (position + step) & tableMask; /* lowprob area */ 147 } 148 } 149 if (position != 0) 150 return ERROR(GENERIC); /* position must reach all cells once, otherwise normalizedCounter is incorrect */ 151 } 152 153 /* Build Decoding table */ 154 { 155 U32 u; 156 for (u = 0; u < tableSize; u++) { 157 FSE_FUNCTION_TYPE const symbol = (FSE_FUNCTION_TYPE)(tableDecode[u].symbol); 158 U16 nextState = symbolNext[symbol]++; 159 tableDecode[u].nbBits = (BYTE)(tableLog - BIT_highbit32((U32)nextState)); 160 tableDecode[u].newState = (U16)((nextState << tableDecode[u].nbBits) - tableSize); 161 } 162 } 163 164 return 0; 165} 166 167/*-******************************************************* 168* Decompression (Byte symbols) 169*********************************************************/ 170size_t FSE_buildDTable_rle(FSE_DTable *dt, BYTE symbolValue) 171{ 172 void *ptr = dt; 173 FSE_DTableHeader *const DTableH = (FSE_DTableHeader *)ptr; 174 void *dPtr = dt + 1; 175 FSE_decode_t *const cell = (FSE_decode_t *)dPtr; 176 177 DTableH->tableLog = 0; 178 DTableH->fastMode = 0; 179 180 cell->newState = 0; 181 cell->symbol = symbolValue; 182 cell->nbBits = 0; 183 184 return 0; 185} 186 187size_t FSE_buildDTable_raw(FSE_DTable *dt, unsigned nbBits) 188{ 189 void *ptr = dt; 190 FSE_DTableHeader *const DTableH = (FSE_DTableHeader *)ptr; 191 void *dPtr = dt + 1; 192 FSE_decode_t *const dinfo = (FSE_decode_t *)dPtr; 193 const unsigned tableSize = 1 << nbBits; 194 const unsigned tableMask = tableSize - 1; 195 const unsigned maxSV1 = tableMask + 1; 196 unsigned s; 197 198 /* Sanity checks */ 199 if (nbBits < 1) 200 return ERROR(GENERIC); /* min size */ 201 202 /* Build Decoding Table */ 203 DTableH->tableLog = (U16)nbBits; 204 DTableH->fastMode = 1; 205 for (s = 0; s < maxSV1; s++) { 206 dinfo[s].newState = 0; 207 dinfo[s].symbol = (BYTE)s; 208 dinfo[s].nbBits = (BYTE)nbBits; 209 } 210 211 return 0; 212} 213 214FORCE_INLINE size_t FSE_decompress_usingDTable_generic(void *dst, size_t maxDstSize, const void *cSrc, size_t cSrcSize, const FSE_DTable *dt, 215 const unsigned fast) 216{ 217 BYTE *const ostart = (BYTE *)dst; 218 BYTE *op = ostart; 219 BYTE *const omax = op + maxDstSize; 220 BYTE *const olimit = omax - 3; 221 222 BIT_DStream_t bitD; 223 FSE_DState_t state1; 224 FSE_DState_t state2; 225 226 /* Init */ 227 CHECK_F(BIT_initDStream(&bitD, cSrc, cSrcSize)); 228 229 FSE_initDState(&state1, &bitD, dt); 230 FSE_initDState(&state2, &bitD, dt); 231 232#define FSE_GETSYMBOL(statePtr) fast ? FSE_decodeSymbolFast(statePtr, &bitD) : FSE_decodeSymbol(statePtr, &bitD) 233 234 /* 4 symbols per loop */ 235 for (; (BIT_reloadDStream(&bitD) == BIT_DStream_unfinished) & (op < olimit); op += 4) { 236 op[0] = FSE_GETSYMBOL(&state1); 237 238 if (FSE_MAX_TABLELOG * 2 + 7 > sizeof(bitD.bitContainer) * 8) /* This test must be static */ 239 BIT_reloadDStream(&bitD); 240 241 op[1] = FSE_GETSYMBOL(&state2); 242 243 if (FSE_MAX_TABLELOG * 4 + 7 > sizeof(bitD.bitContainer) * 8) /* This test must be static */ 244 { 245 if (BIT_reloadDStream(&bitD) > BIT_DStream_unfinished) { 246 op += 2; 247 break; 248 } 249 } 250 251 op[2] = FSE_GETSYMBOL(&state1); 252 253 if (FSE_MAX_TABLELOG * 2 + 7 > sizeof(bitD.bitContainer) * 8) /* This test must be static */ 254 BIT_reloadDStream(&bitD); 255 256 op[3] = FSE_GETSYMBOL(&state2); 257 } 258 259 /* tail */ 260 /* note : BIT_reloadDStream(&bitD) >= FSE_DStream_partiallyFilled; Ends at exactly BIT_DStream_completed */ 261 while (1) { 262 if (op > (omax - 2)) 263 return ERROR(dstSize_tooSmall); 264 *op++ = FSE_GETSYMBOL(&state1); 265 if (BIT_reloadDStream(&bitD) == BIT_DStream_overflow) { 266 *op++ = FSE_GETSYMBOL(&state2); 267 break; 268 } 269 270 if (op > (omax - 2)) 271 return ERROR(dstSize_tooSmall); 272 *op++ = FSE_GETSYMBOL(&state2); 273 if (BIT_reloadDStream(&bitD) == BIT_DStream_overflow) { 274 *op++ = FSE_GETSYMBOL(&state1); 275 break; 276 } 277 } 278 279 return op - ostart; 280} 281 282size_t FSE_decompress_usingDTable(void *dst, size_t originalSize, const void *cSrc, size_t cSrcSize, const FSE_DTable *dt) 283{ 284 const void *ptr = dt; 285 const FSE_DTableHeader *DTableH = (const FSE_DTableHeader *)ptr; 286 const U32 fastMode = DTableH->fastMode; 287 288 /* select fast mode (static) */ 289 if (fastMode) 290 return FSE_decompress_usingDTable_generic(dst, originalSize, cSrc, cSrcSize, dt, 1); 291 return FSE_decompress_usingDTable_generic(dst, originalSize, cSrc, cSrcSize, dt, 0); 292} 293 294size_t FSE_decompress_wksp(void *dst, size_t dstCapacity, const void *cSrc, size_t cSrcSize, unsigned maxLog, void *workspace, size_t workspaceSize) 295{ 296 const BYTE *const istart = (const BYTE *)cSrc; 297 const BYTE *ip = istart; 298 unsigned tableLog; 299 unsigned maxSymbolValue = FSE_MAX_SYMBOL_VALUE; 300 size_t NCountLength; 301 302 FSE_DTable *dt; 303 short *counting; 304 size_t spaceUsed32 = 0; 305 306 FSE_STATIC_ASSERT(sizeof(FSE_DTable) == sizeof(U32)); 307 308 dt = (FSE_DTable *)((U32 *)workspace + spaceUsed32); 309 spaceUsed32 += FSE_DTABLE_SIZE_U32(maxLog); 310 counting = (short *)((U32 *)workspace + spaceUsed32); 311 spaceUsed32 += ALIGN(sizeof(short) * (FSE_MAX_SYMBOL_VALUE + 1), sizeof(U32)) >> 2; 312 313 if ((spaceUsed32 << 2) > workspaceSize) 314 return ERROR(tableLog_tooLarge); 315 workspace = (U32 *)workspace + spaceUsed32; 316 workspaceSize -= (spaceUsed32 << 2); 317 318 /* normal FSE decoding mode */ 319 NCountLength = FSE_readNCount(counting, &maxSymbolValue, &tableLog, istart, cSrcSize); 320 if (FSE_isError(NCountLength)) 321 return NCountLength; 322 // if (NCountLength >= cSrcSize) return ERROR(srcSize_wrong); /* too small input size; supposed to be already checked in NCountLength, only remaining 323 // case : NCountLength==cSrcSize */ 324 if (tableLog > maxLog) 325 return ERROR(tableLog_tooLarge); 326 ip += NCountLength; 327 cSrcSize -= NCountLength; 328 329 CHECK_F(FSE_buildDTable_wksp(dt, counting, maxSymbolValue, tableLog, workspace, workspaceSize)); 330 331 return FSE_decompress_usingDTable(dst, dstCapacity, ip, cSrcSize, dt); /* always return, even if it is an error code */ 332}