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 "zstd_internal.h" 51#include <linux/compiler.h> 52#include <linux/kernel.h> 53#include <linux/string.h> /* memcpy, memset */ 54 55/* ************************************************************** 56* Error Management 57****************************************************************/ 58#define FSE_isError ERR_isError 59#define FSE_STATIC_ASSERT(c) \ 60 { \ 61 enum { FSE_static_assert = 1 / (int)(!!(c)) }; \ 62 } /* use only *after* variable declarations */ 63 64/* ************************************************************** 65* Templates 66****************************************************************/ 67/* 68 designed to be included 69 for type-specific functions (template emulation in C) 70 Objective is to write these functions only once, for improved maintenance 71*/ 72 73/* safety checks */ 74#ifndef FSE_FUNCTION_EXTENSION 75#error "FSE_FUNCTION_EXTENSION must be defined" 76#endif 77#ifndef FSE_FUNCTION_TYPE 78#error "FSE_FUNCTION_TYPE must be defined" 79#endif 80 81/* Function names */ 82#define FSE_CAT(X, Y) X##Y 83#define FSE_FUNCTION_NAME(X, Y) FSE_CAT(X, Y) 84#define FSE_TYPE_NAME(X, Y) FSE_CAT(X, Y) 85 86/* Function templates */ 87 88size_t FSE_buildDTable_wksp(FSE_DTable *dt, const short *normalizedCounter, unsigned maxSymbolValue, unsigned tableLog, void *workspace, size_t workspaceSize) 89{ 90 void *const tdPtr = dt + 1; /* because *dt is unsigned, 32-bits aligned on 32-bits */ 91 FSE_DECODE_TYPE *const tableDecode = (FSE_DECODE_TYPE *)(tdPtr); 92 U16 *symbolNext = (U16 *)workspace; 93 94 U32 const maxSV1 = maxSymbolValue + 1; 95 U32 const tableSize = 1 << tableLog; 96 U32 highThreshold = tableSize - 1; 97 98 /* Sanity Checks */ 99 if (workspaceSize < sizeof(U16) * (FSE_MAX_SYMBOL_VALUE + 1)) 100 return ERROR(tableLog_tooLarge); 101 if (maxSymbolValue > FSE_MAX_SYMBOL_VALUE) 102 return ERROR(maxSymbolValue_tooLarge); 103 if (tableLog > FSE_MAX_TABLELOG) 104 return ERROR(tableLog_tooLarge); 105 106 /* Init, lay down lowprob symbols */ 107 { 108 FSE_DTableHeader DTableH; 109 DTableH.tableLog = (U16)tableLog; 110 DTableH.fastMode = 1; 111 { 112 S16 const largeLimit = (S16)(1 << (tableLog - 1)); 113 U32 s; 114 for (s = 0; s < maxSV1; s++) { 115 if (normalizedCounter[s] == -1) { 116 tableDecode[highThreshold--].symbol = (FSE_FUNCTION_TYPE)s; 117 symbolNext[s] = 1; 118 } else { 119 if (normalizedCounter[s] >= largeLimit) 120 DTableH.fastMode = 0; 121 symbolNext[s] = normalizedCounter[s]; 122 } 123 } 124 } 125 memcpy(dt, &DTableH, sizeof(DTableH)); 126 } 127 128 /* Spread symbols */ 129 { 130 U32 const tableMask = tableSize - 1; 131 U32 const step = FSE_TABLESTEP(tableSize); 132 U32 s, position = 0; 133 for (s = 0; s < maxSV1; s++) { 134 int i; 135 for (i = 0; i < normalizedCounter[s]; i++) { 136 tableDecode[position].symbol = (FSE_FUNCTION_TYPE)s; 137 position = (position + step) & tableMask; 138 while (position > highThreshold) 139 position = (position + step) & tableMask; /* lowprob area */ 140 } 141 } 142 if (position != 0) 143 return ERROR(GENERIC); /* position must reach all cells once, otherwise normalizedCounter is incorrect */ 144 } 145 146 /* Build Decoding table */ 147 { 148 U32 u; 149 for (u = 0; u < tableSize; u++) { 150 FSE_FUNCTION_TYPE const symbol = (FSE_FUNCTION_TYPE)(tableDecode[u].symbol); 151 U16 nextState = symbolNext[symbol]++; 152 tableDecode[u].nbBits = (BYTE)(tableLog - BIT_highbit32((U32)nextState)); 153 tableDecode[u].newState = (U16)((nextState << tableDecode[u].nbBits) - tableSize); 154 } 155 } 156 157 return 0; 158} 159 160/*-******************************************************* 161* Decompression (Byte symbols) 162*********************************************************/ 163size_t FSE_buildDTable_rle(FSE_DTable *dt, BYTE symbolValue) 164{ 165 void *ptr = dt; 166 FSE_DTableHeader *const DTableH = (FSE_DTableHeader *)ptr; 167 void *dPtr = dt + 1; 168 FSE_decode_t *const cell = (FSE_decode_t *)dPtr; 169 170 DTableH->tableLog = 0; 171 DTableH->fastMode = 0; 172 173 cell->newState = 0; 174 cell->symbol = symbolValue; 175 cell->nbBits = 0; 176 177 return 0; 178} 179 180size_t FSE_buildDTable_raw(FSE_DTable *dt, unsigned nbBits) 181{ 182 void *ptr = dt; 183 FSE_DTableHeader *const DTableH = (FSE_DTableHeader *)ptr; 184 void *dPtr = dt + 1; 185 FSE_decode_t *const dinfo = (FSE_decode_t *)dPtr; 186 const unsigned tableSize = 1 << nbBits; 187 const unsigned tableMask = tableSize - 1; 188 const unsigned maxSV1 = tableMask + 1; 189 unsigned s; 190 191 /* Sanity checks */ 192 if (nbBits < 1) 193 return ERROR(GENERIC); /* min size */ 194 195 /* Build Decoding Table */ 196 DTableH->tableLog = (U16)nbBits; 197 DTableH->fastMode = 1; 198 for (s = 0; s < maxSV1; s++) { 199 dinfo[s].newState = 0; 200 dinfo[s].symbol = (BYTE)s; 201 dinfo[s].nbBits = (BYTE)nbBits; 202 } 203 204 return 0; 205} 206 207FORCE_INLINE size_t FSE_decompress_usingDTable_generic(void *dst, size_t maxDstSize, const void *cSrc, size_t cSrcSize, const FSE_DTable *dt, 208 const unsigned fast) 209{ 210 BYTE *const ostart = (BYTE *)dst; 211 BYTE *op = ostart; 212 BYTE *const omax = op + maxDstSize; 213 BYTE *const olimit = omax - 3; 214 215 BIT_DStream_t bitD; 216 FSE_DState_t state1; 217 FSE_DState_t state2; 218 219 /* Init */ 220 CHECK_F(BIT_initDStream(&bitD, cSrc, cSrcSize)); 221 222 FSE_initDState(&state1, &bitD, dt); 223 FSE_initDState(&state2, &bitD, dt); 224 225#define FSE_GETSYMBOL(statePtr) fast ? FSE_decodeSymbolFast(statePtr, &bitD) : FSE_decodeSymbol(statePtr, &bitD) 226 227 /* 4 symbols per loop */ 228 for (; (BIT_reloadDStream(&bitD) == BIT_DStream_unfinished) & (op < olimit); op += 4) { 229 op[0] = FSE_GETSYMBOL(&state1); 230 231 if (FSE_MAX_TABLELOG * 2 + 7 > sizeof(bitD.bitContainer) * 8) /* This test must be static */ 232 BIT_reloadDStream(&bitD); 233 234 op[1] = FSE_GETSYMBOL(&state2); 235 236 if (FSE_MAX_TABLELOG * 4 + 7 > sizeof(bitD.bitContainer) * 8) /* This test must be static */ 237 { 238 if (BIT_reloadDStream(&bitD) > BIT_DStream_unfinished) { 239 op += 2; 240 break; 241 } 242 } 243 244 op[2] = FSE_GETSYMBOL(&state1); 245 246 if (FSE_MAX_TABLELOG * 2 + 7 > sizeof(bitD.bitContainer) * 8) /* This test must be static */ 247 BIT_reloadDStream(&bitD); 248 249 op[3] = FSE_GETSYMBOL(&state2); 250 } 251 252 /* tail */ 253 /* note : BIT_reloadDStream(&bitD) >= FSE_DStream_partiallyFilled; Ends at exactly BIT_DStream_completed */ 254 while (1) { 255 if (op > (omax - 2)) 256 return ERROR(dstSize_tooSmall); 257 *op++ = FSE_GETSYMBOL(&state1); 258 if (BIT_reloadDStream(&bitD) == BIT_DStream_overflow) { 259 *op++ = FSE_GETSYMBOL(&state2); 260 break; 261 } 262 263 if (op > (omax - 2)) 264 return ERROR(dstSize_tooSmall); 265 *op++ = FSE_GETSYMBOL(&state2); 266 if (BIT_reloadDStream(&bitD) == BIT_DStream_overflow) { 267 *op++ = FSE_GETSYMBOL(&state1); 268 break; 269 } 270 } 271 272 return op - ostart; 273} 274 275size_t FSE_decompress_usingDTable(void *dst, size_t originalSize, const void *cSrc, size_t cSrcSize, const FSE_DTable *dt) 276{ 277 const void *ptr = dt; 278 const FSE_DTableHeader *DTableH = (const FSE_DTableHeader *)ptr; 279 const U32 fastMode = DTableH->fastMode; 280 281 /* select fast mode (static) */ 282 if (fastMode) 283 return FSE_decompress_usingDTable_generic(dst, originalSize, cSrc, cSrcSize, dt, 1); 284 return FSE_decompress_usingDTable_generic(dst, originalSize, cSrc, cSrcSize, dt, 0); 285} 286 287size_t FSE_decompress_wksp(void *dst, size_t dstCapacity, const void *cSrc, size_t cSrcSize, unsigned maxLog, void *workspace, size_t workspaceSize) 288{ 289 const BYTE *const istart = (const BYTE *)cSrc; 290 const BYTE *ip = istart; 291 unsigned tableLog; 292 unsigned maxSymbolValue = FSE_MAX_SYMBOL_VALUE; 293 size_t NCountLength; 294 295 FSE_DTable *dt; 296 short *counting; 297 size_t spaceUsed32 = 0; 298 299 FSE_STATIC_ASSERT(sizeof(FSE_DTable) == sizeof(U32)); 300 301 dt = (FSE_DTable *)((U32 *)workspace + spaceUsed32); 302 spaceUsed32 += FSE_DTABLE_SIZE_U32(maxLog); 303 counting = (short *)((U32 *)workspace + spaceUsed32); 304 spaceUsed32 += ALIGN(sizeof(short) * (FSE_MAX_SYMBOL_VALUE + 1), sizeof(U32)) >> 2; 305 306 if ((spaceUsed32 << 2) > workspaceSize) 307 return ERROR(tableLog_tooLarge); 308 workspace = (U32 *)workspace + spaceUsed32; 309 workspaceSize -= (spaceUsed32 << 2); 310 311 /* normal FSE decoding mode */ 312 NCountLength = FSE_readNCount(counting, &maxSymbolValue, &tableLog, istart, cSrcSize); 313 if (FSE_isError(NCountLength)) 314 return NCountLength; 315 // if (NCountLength >= cSrcSize) return ERROR(srcSize_wrong); /* too small input size; supposed to be already checked in NCountLength, only remaining 316 // case : NCountLength==cSrcSize */ 317 if (tableLog > maxLog) 318 return ERROR(tableLog_tooLarge); 319 ip += NCountLength; 320 cSrcSize -= NCountLength; 321 322 CHECK_F(FSE_buildDTable_wksp(dt, counting, maxSymbolValue, tableLog, workspace, workspaceSize)); 323 324 return FSE_decompress_usingDTable(dst, dstCapacity, ip, cSrcSize, dt); /* always return, even if it is an error code */ 325} 326