1 /* ****************************************************************** 2 FSE : Finite State Entropy encoder 3 Copyright (C) 2013-present, 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 You can contact the author at : 31 - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy 32 - Public forum : https://groups.google.com/forum/#!forum/lz4c 33 ****************************************************************** */ 34 35 /* ************************************************************** 36 * Includes 37 ****************************************************************/ 38 #include <stdlib.h> /* malloc, free, qsort */ 39 #include <string.h> /* memcpy, memset */ 40 #include "compiler.h" 41 #include "mem.h" /* U32, U16, etc. */ 42 #include "debug.h" /* assert, DEBUGLOG */ 43 #include "hist.h" /* HIST_count_wksp */ 44 #include "bitstream.h" 45 #define FSE_STATIC_LINKING_ONLY 46 #include "fse.h" 47 #include "error_private.h" 48 #include <ntifs.h> 49 #include <ntddk.h> 50 51 52 /* ************************************************************** 53 * Error Management 54 ****************************************************************/ 55 #define FSE_isError ERR_isError 56 57 58 /* ************************************************************** 59 * Templates 60 ****************************************************************/ 61 /* 62 designed to be included 63 for type-specific functions (template emulation in C) 64 Objective is to write these functions only once, for improved maintenance 65 */ 66 67 /* safety checks */ 68 #ifndef FSE_FUNCTION_EXTENSION 69 # error "FSE_FUNCTION_EXTENSION must be defined" 70 #endif 71 #ifndef FSE_FUNCTION_TYPE 72 # error "FSE_FUNCTION_TYPE must be defined" 73 #endif 74 75 /* Function names */ 76 #define FSE_CAT(X,Y) X##Y 77 #define FSE_FUNCTION_NAME(X,Y) FSE_CAT(X,Y) 78 #define FSE_TYPE_NAME(X,Y) FSE_CAT(X,Y) 79 80 #define FSEC_ALLOC_TAG 0x64455346 // "FSEc" 81 82 /* Function templates */ 83 84 /* FSE_buildCTable_wksp() : 85 * Same as FSE_buildCTable(), but using an externally allocated scratch buffer (`workSpace`). 86 * wkspSize should be sized to handle worst case situation, which is `1<<max_tableLog * sizeof(FSE_FUNCTION_TYPE)` 87 * workSpace must also be properly aligned with FSE_FUNCTION_TYPE requirements 88 */ 89 size_t FSE_buildCTable_wksp(FSE_CTable* ct, 90 const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog, 91 void* workSpace, size_t wkspSize) 92 { 93 U32 const tableSize = 1 << tableLog; 94 U32 const tableMask = tableSize - 1; 95 void* const ptr = ct; 96 U16* const tableU16 = ( (U16*) ptr) + 2; 97 void* const FSCT = ((U32*)ptr) + 1 /* header */ + (tableLog ? tableSize>>1 : 1) ; 98 FSE_symbolCompressionTransform* const symbolTT = (FSE_symbolCompressionTransform*) (FSCT); 99 U32 const step = FSE_TABLESTEP(tableSize); 100 U32 cumul[FSE_MAX_SYMBOL_VALUE+2]; 101 102 FSE_FUNCTION_TYPE* const tableSymbol = (FSE_FUNCTION_TYPE*)workSpace; 103 U32 highThreshold = tableSize-1; 104 105 /* CTable header */ 106 if (((size_t)1 << tableLog) * sizeof(FSE_FUNCTION_TYPE) > wkspSize) return ERROR(tableLog_tooLarge); 107 tableU16[-2] = (U16) tableLog; 108 tableU16[-1] = (U16) maxSymbolValue; 109 assert(tableLog < 16); /* required for threshold strategy to work */ 110 111 /* For explanations on how to distribute symbol values over the table : 112 * http://fastcompression.blogspot.fr/2014/02/fse-distributing-symbol-values.html */ 113 114 #ifdef __clang_analyzer__ 115 memset(tableSymbol, 0, sizeof(*tableSymbol) * tableSize); /* useless initialization, just to keep scan-build happy */ 116 #endif 117 118 /* symbol start positions */ 119 { U32 u; 120 cumul[0] = 0; 121 for (u=1; u<=maxSymbolValue+1; u++) { 122 if (normalizedCounter[u-1]==-1) { /* Low proba symbol */ 123 cumul[u] = cumul[u-1] + 1; 124 tableSymbol[highThreshold--] = (FSE_FUNCTION_TYPE)(u-1); 125 } else { 126 cumul[u] = cumul[u-1] + normalizedCounter[u-1]; 127 } } 128 cumul[maxSymbolValue+1] = tableSize+1; 129 } 130 131 /* Spread symbols */ 132 { U32 position = 0; 133 U32 symbol; 134 for (symbol=0; symbol<=maxSymbolValue; symbol++) { 135 int nbOccurences; 136 int const freq = normalizedCounter[symbol]; 137 for (nbOccurences=0; nbOccurences<freq; nbOccurences++) { 138 tableSymbol[position] = (FSE_FUNCTION_TYPE)symbol; 139 position = (position + step) & tableMask; 140 while (position > highThreshold) 141 position = (position + step) & tableMask; /* Low proba area */ 142 } } 143 144 assert(position==0); /* Must have initialized all positions */ 145 } 146 147 /* Build table */ 148 { U32 u; for (u=0; u<tableSize; u++) { 149 FSE_FUNCTION_TYPE s = tableSymbol[u]; /* note : static analyzer may not understand tableSymbol is properly initialized */ 150 tableU16[cumul[s]++] = (U16) (tableSize+u); /* TableU16 : sorted by symbol order; gives next state value */ 151 } } 152 153 /* Build Symbol Transformation Table */ 154 { unsigned total = 0; 155 unsigned s; 156 for (s=0; s<=maxSymbolValue; s++) { 157 switch (normalizedCounter[s]) 158 { 159 case 0: 160 /* filling nonetheless, for compatibility with FSE_getMaxNbBits() */ 161 symbolTT[s].deltaNbBits = ((tableLog+1) << 16) - (1<<tableLog); 162 break; 163 164 case -1: 165 case 1: 166 symbolTT[s].deltaNbBits = (tableLog << 16) - (1<<tableLog); 167 symbolTT[s].deltaFindState = total - 1; 168 total ++; 169 break; 170 default : 171 { 172 U32 const maxBitsOut = tableLog - BIT_highbit32 (normalizedCounter[s]-1); 173 U32 const minStatePlus = normalizedCounter[s] << maxBitsOut; 174 symbolTT[s].deltaNbBits = (maxBitsOut << 16) - minStatePlus; 175 symbolTT[s].deltaFindState = total - normalizedCounter[s]; 176 total += normalizedCounter[s]; 177 } } } } 178 179 #if 0 /* debug : symbol costs */ 180 DEBUGLOG(5, "\n --- table statistics : "); 181 { U32 symbol; 182 for (symbol=0; symbol<=maxSymbolValue; symbol++) { 183 DEBUGLOG(5, "%3u: w=%3i, maxBits=%u, fracBits=%.2f", 184 symbol, normalizedCounter[symbol], 185 FSE_getMaxNbBits(symbolTT, symbol), 186 (double)FSE_bitCost(symbolTT, tableLog, symbol, 8) / 256); 187 } 188 } 189 #endif 190 191 return 0; 192 } 193 194 195 size_t FSE_buildCTable(FSE_CTable* ct, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog) 196 { 197 FSE_FUNCTION_TYPE* tableSymbol = ExAllocatePoolWithTag(NonPagedPool, sizeof(FSE_FUNCTION_TYPE) * FSE_MAX_TABLESIZE, FSEC_ALLOC_TAG); 198 size_t ret; 199 200 if (!tableSymbol) 201 return 0; 202 203 ret = FSE_buildCTable_wksp(ct, normalizedCounter, maxSymbolValue, tableLog, tableSymbol, sizeof(FSE_FUNCTION_TYPE) * FSE_MAX_TABLESIZE); 204 205 ExFreePool(tableSymbol); 206 207 return ret; 208 } 209 210 211 212 #ifndef FSE_COMMONDEFS_ONLY 213 214 215 /*-************************************************************** 216 * FSE NCount encoding 217 ****************************************************************/ 218 size_t FSE_NCountWriteBound(unsigned maxSymbolValue, unsigned tableLog) 219 { 220 size_t const maxHeaderSize = (((maxSymbolValue+1) * tableLog) >> 3) + 3; 221 return maxSymbolValue ? maxHeaderSize : FSE_NCOUNTBOUND; /* maxSymbolValue==0 ? use default */ 222 } 223 224 static size_t 225 FSE_writeNCount_generic (void* header, size_t headerBufferSize, 226 const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog, 227 unsigned writeIsSafe) 228 { 229 BYTE* const ostart = (BYTE*) header; 230 BYTE* out = ostart; 231 BYTE* const oend = ostart + headerBufferSize; 232 int nbBits; 233 const int tableSize = 1 << tableLog; 234 int remaining; 235 int threshold; 236 U32 bitStream = 0; 237 int bitCount = 0; 238 unsigned symbol = 0; 239 unsigned const alphabetSize = maxSymbolValue + 1; 240 int previousIs0 = 0; 241 242 /* Table Size */ 243 bitStream += (tableLog-FSE_MIN_TABLELOG) << bitCount; 244 bitCount += 4; 245 246 /* Init */ 247 remaining = tableSize+1; /* +1 for extra accuracy */ 248 threshold = tableSize; 249 nbBits = tableLog+1; 250 251 while ((symbol < alphabetSize) && (remaining>1)) { /* stops at 1 */ 252 if (previousIs0) { 253 unsigned start = symbol; 254 while ((symbol < alphabetSize) && !normalizedCounter[symbol]) symbol++; 255 if (symbol == alphabetSize) break; /* incorrect distribution */ 256 while (symbol >= start+24) { 257 start+=24; 258 bitStream += 0xFFFFU << bitCount; 259 if ((!writeIsSafe) && (out > oend-2)) 260 return ERROR(dstSize_tooSmall); /* Buffer overflow */ 261 out[0] = (BYTE) bitStream; 262 out[1] = (BYTE)(bitStream>>8); 263 out+=2; 264 bitStream>>=16; 265 } 266 while (symbol >= start+3) { 267 start+=3; 268 bitStream += 3 << bitCount; 269 bitCount += 2; 270 } 271 bitStream += (symbol-start) << bitCount; 272 bitCount += 2; 273 if (bitCount>16) { 274 if ((!writeIsSafe) && (out > oend - 2)) 275 return ERROR(dstSize_tooSmall); /* Buffer overflow */ 276 out[0] = (BYTE)bitStream; 277 out[1] = (BYTE)(bitStream>>8); 278 out += 2; 279 bitStream >>= 16; 280 bitCount -= 16; 281 } } 282 { int count = normalizedCounter[symbol++]; 283 int const max = (2*threshold-1) - remaining; 284 remaining -= count < 0 ? -count : count; 285 count++; /* +1 for extra accuracy */ 286 if (count>=threshold) 287 count += max; /* [0..max[ [max..threshold[ (...) [threshold+max 2*threshold[ */ 288 bitStream += count << bitCount; 289 bitCount += nbBits; 290 bitCount -= (count<max); 291 previousIs0 = (count==1); 292 if (remaining<1) return ERROR(GENERIC); 293 while (remaining<threshold) { nbBits--; threshold>>=1; } 294 } 295 if (bitCount>16) { 296 if ((!writeIsSafe) && (out > oend - 2)) 297 return ERROR(dstSize_tooSmall); /* Buffer overflow */ 298 out[0] = (BYTE)bitStream; 299 out[1] = (BYTE)(bitStream>>8); 300 out += 2; 301 bitStream >>= 16; 302 bitCount -= 16; 303 } } 304 305 if (remaining != 1) 306 return ERROR(GENERIC); /* incorrect normalized distribution */ 307 assert(symbol <= alphabetSize); 308 309 /* flush remaining bitStream */ 310 if ((!writeIsSafe) && (out > oend - 2)) 311 return ERROR(dstSize_tooSmall); /* Buffer overflow */ 312 out[0] = (BYTE)bitStream; 313 out[1] = (BYTE)(bitStream>>8); 314 out+= (bitCount+7) /8; 315 316 return (out-ostart); 317 } 318 319 320 size_t FSE_writeNCount (void* buffer, size_t bufferSize, 321 const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog) 322 { 323 if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge); /* Unsupported */ 324 if (tableLog < FSE_MIN_TABLELOG) return ERROR(GENERIC); /* Unsupported */ 325 326 if (bufferSize < FSE_NCountWriteBound(maxSymbolValue, tableLog)) 327 return FSE_writeNCount_generic(buffer, bufferSize, normalizedCounter, maxSymbolValue, tableLog, 0); 328 329 return FSE_writeNCount_generic(buffer, bufferSize, normalizedCounter, maxSymbolValue, tableLog, 1 /* write in buffer is safe */); 330 } 331 332 333 /*-************************************************************** 334 * FSE Compression Code 335 ****************************************************************/ 336 337 FSE_CTable* FSE_createCTable (unsigned maxSymbolValue, unsigned tableLog) 338 { 339 size_t size; 340 if (tableLog > FSE_TABLELOG_ABSOLUTE_MAX) tableLog = FSE_TABLELOG_ABSOLUTE_MAX; 341 size = FSE_CTABLE_SIZE_U32 (tableLog, maxSymbolValue) * sizeof(U32); 342 return (FSE_CTable*)ExAllocatePoolWithTag(PagedPool, size, FSEC_ALLOC_TAG); 343 } 344 345 void FSE_freeCTable (FSE_CTable* ct) { ExFreePool(ct); } 346 347 /* provides the minimum logSize to safely represent a distribution */ 348 static unsigned FSE_minTableLog(size_t srcSize, unsigned maxSymbolValue) 349 { 350 U32 minBitsSrc = BIT_highbit32((U32)(srcSize)) + 1; 351 U32 minBitsSymbols = BIT_highbit32(maxSymbolValue) + 2; 352 U32 minBits = minBitsSrc < minBitsSymbols ? minBitsSrc : minBitsSymbols; 353 assert(srcSize > 1); /* Not supported, RLE should be used instead */ 354 return minBits; 355 } 356 357 unsigned FSE_optimalTableLog_internal(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue, unsigned minus) 358 { 359 U32 maxBitsSrc = BIT_highbit32((U32)(srcSize - 1)) - minus; 360 U32 tableLog = maxTableLog; 361 U32 minBits = FSE_minTableLog(srcSize, maxSymbolValue); 362 assert(srcSize > 1); /* Not supported, RLE should be used instead */ 363 if (tableLog==0) tableLog = FSE_DEFAULT_TABLELOG; 364 if (maxBitsSrc < tableLog) tableLog = maxBitsSrc; /* Accuracy can be reduced */ 365 if (minBits > tableLog) tableLog = minBits; /* Need a minimum to safely represent all symbol values */ 366 if (tableLog < FSE_MIN_TABLELOG) tableLog = FSE_MIN_TABLELOG; 367 if (tableLog > FSE_MAX_TABLELOG) tableLog = FSE_MAX_TABLELOG; 368 return tableLog; 369 } 370 371 unsigned FSE_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue) 372 { 373 return FSE_optimalTableLog_internal(maxTableLog, srcSize, maxSymbolValue, 2); 374 } 375 376 377 /* Secondary normalization method. 378 To be used when primary method fails. */ 379 380 static size_t FSE_normalizeM2(short* norm, U32 tableLog, const unsigned* count, size_t total, U32 maxSymbolValue) 381 { 382 short const NOT_YET_ASSIGNED = -2; 383 U32 s; 384 U32 distributed = 0; 385 U32 ToDistribute; 386 387 /* Init */ 388 U32 const lowThreshold = (U32)(total >> tableLog); 389 U32 lowOne = (U32)((total * 3) >> (tableLog + 1)); 390 391 for (s=0; s<=maxSymbolValue; s++) { 392 if (count[s] == 0) { 393 norm[s]=0; 394 continue; 395 } 396 if (count[s] <= lowThreshold) { 397 norm[s] = -1; 398 distributed++; 399 total -= count[s]; 400 continue; 401 } 402 if (count[s] <= lowOne) { 403 norm[s] = 1; 404 distributed++; 405 total -= count[s]; 406 continue; 407 } 408 409 norm[s]=NOT_YET_ASSIGNED; 410 } 411 ToDistribute = (1 << tableLog) - distributed; 412 413 if (ToDistribute == 0) 414 return 0; 415 416 if ((total / ToDistribute) > lowOne) { 417 /* risk of rounding to zero */ 418 lowOne = (U32)((total * 3) / (ToDistribute * 2)); 419 for (s=0; s<=maxSymbolValue; s++) { 420 if ((norm[s] == NOT_YET_ASSIGNED) && (count[s] <= lowOne)) { 421 norm[s] = 1; 422 distributed++; 423 total -= count[s]; 424 continue; 425 } } 426 ToDistribute = (1 << tableLog) - distributed; 427 } 428 429 if (distributed == maxSymbolValue+1) { 430 /* all values are pretty poor; 431 probably incompressible data (should have already been detected); 432 find max, then give all remaining points to max */ 433 U32 maxV = 0, maxC = 0; 434 for (s=0; s<=maxSymbolValue; s++) 435 if (count[s] > maxC) { maxV=s; maxC=count[s]; } 436 norm[maxV] += (short)ToDistribute; 437 return 0; 438 } 439 440 if (total == 0) { 441 /* all of the symbols were low enough for the lowOne or lowThreshold */ 442 for (s=0; ToDistribute > 0; s = (s+1)%(maxSymbolValue+1)) 443 if (norm[s] > 0) { ToDistribute--; norm[s]++; } 444 return 0; 445 } 446 447 { U64 const vStepLog = 62 - tableLog; 448 U64 const mid = (1ULL << (vStepLog-1)) - 1; 449 U64 const rStep = ((((U64)1<<vStepLog) * ToDistribute) + mid) / total; /* scale on remaining */ 450 U64 tmpTotal = mid; 451 for (s=0; s<=maxSymbolValue; s++) { 452 if (norm[s]==NOT_YET_ASSIGNED) { 453 U64 const end = tmpTotal + (count[s] * rStep); 454 U32 const sStart = (U32)(tmpTotal >> vStepLog); 455 U32 const sEnd = (U32)(end >> vStepLog); 456 U32 const weight = sEnd - sStart; 457 if (weight < 1) 458 return ERROR(GENERIC); 459 norm[s] = (short)weight; 460 tmpTotal = end; 461 } } } 462 463 return 0; 464 } 465 466 467 size_t FSE_normalizeCount (short* normalizedCounter, unsigned tableLog, 468 const unsigned* count, size_t total, 469 unsigned maxSymbolValue) 470 { 471 /* Sanity checks */ 472 if (tableLog==0) tableLog = FSE_DEFAULT_TABLELOG; 473 if (tableLog < FSE_MIN_TABLELOG) return ERROR(GENERIC); /* Unsupported size */ 474 if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge); /* Unsupported size */ 475 if (tableLog < FSE_minTableLog(total, maxSymbolValue)) return ERROR(GENERIC); /* Too small tableLog, compression potentially impossible */ 476 477 { static U32 const rtbTable[] = { 0, 473195, 504333, 520860, 550000, 700000, 750000, 830000 }; 478 U64 const scale = 62 - tableLog; 479 U64 const step = ((U64)1<<62) / total; /* <== here, one division ! */ 480 U64 const vStep = 1ULL<<(scale-20); 481 int stillToDistribute = 1<<tableLog; 482 unsigned s; 483 unsigned largest=0; 484 short largestP=0; 485 U32 lowThreshold = (U32)(total >> tableLog); 486 487 for (s=0; s<=maxSymbolValue; s++) { 488 if (count[s] == total) return 0; /* rle special case */ 489 if (count[s] == 0) { normalizedCounter[s]=0; continue; } 490 if (count[s] <= lowThreshold) { 491 normalizedCounter[s] = -1; 492 stillToDistribute--; 493 } else { 494 short proba = (short)((count[s]*step) >> scale); 495 if (proba<8) { 496 U64 restToBeat = vStep * rtbTable[proba]; 497 proba += (count[s]*step) - ((U64)proba<<scale) > restToBeat; 498 } 499 if (proba > largestP) { largestP=proba; largest=s; } 500 normalizedCounter[s] = proba; 501 stillToDistribute -= proba; 502 } } 503 if (-stillToDistribute >= (normalizedCounter[largest] >> 1)) { 504 /* corner case, need another normalization method */ 505 size_t const errorCode = FSE_normalizeM2(normalizedCounter, tableLog, count, total, maxSymbolValue); 506 if (FSE_isError(errorCode)) return errorCode; 507 } 508 else normalizedCounter[largest] += (short)stillToDistribute; 509 } 510 511 #if 0 512 { /* Print Table (debug) */ 513 U32 s; 514 U32 nTotal = 0; 515 for (s=0; s<=maxSymbolValue; s++) 516 RAWLOG(2, "%3i: %4i \n", s, normalizedCounter[s]); 517 for (s=0; s<=maxSymbolValue; s++) 518 nTotal += abs(normalizedCounter[s]); 519 if (nTotal != (1U<<tableLog)) 520 RAWLOG(2, "Warning !!! Total == %u != %u !!!", nTotal, 1U<<tableLog); 521 getchar(); 522 } 523 #endif 524 525 return tableLog; 526 } 527 528 529 /* fake FSE_CTable, for raw (uncompressed) input */ 530 size_t FSE_buildCTable_raw (FSE_CTable* ct, unsigned nbBits) 531 { 532 const unsigned tableSize = 1 << nbBits; 533 const unsigned tableMask = tableSize - 1; 534 const unsigned maxSymbolValue = tableMask; 535 void* const ptr = ct; 536 U16* const tableU16 = ( (U16*) ptr) + 2; 537 void* const FSCT = ((U32*)ptr) + 1 /* header */ + (tableSize>>1); /* assumption : tableLog >= 1 */ 538 FSE_symbolCompressionTransform* const symbolTT = (FSE_symbolCompressionTransform*) (FSCT); 539 unsigned s; 540 541 /* Sanity checks */ 542 if (nbBits < 1) return ERROR(GENERIC); /* min size */ 543 544 /* header */ 545 tableU16[-2] = (U16) nbBits; 546 tableU16[-1] = (U16) maxSymbolValue; 547 548 /* Build table */ 549 for (s=0; s<tableSize; s++) 550 tableU16[s] = (U16)(tableSize + s); 551 552 /* Build Symbol Transformation Table */ 553 { const U32 deltaNbBits = (nbBits << 16) - (1 << nbBits); 554 for (s=0; s<=maxSymbolValue; s++) { 555 symbolTT[s].deltaNbBits = deltaNbBits; 556 symbolTT[s].deltaFindState = s-1; 557 } } 558 559 return 0; 560 } 561 562 /* fake FSE_CTable, for rle input (always same symbol) */ 563 size_t FSE_buildCTable_rle (FSE_CTable* ct, BYTE symbolValue) 564 { 565 void* ptr = ct; 566 U16* tableU16 = ( (U16*) ptr) + 2; 567 void* FSCTptr = (U32*)ptr + 2; 568 FSE_symbolCompressionTransform* symbolTT = (FSE_symbolCompressionTransform*) FSCTptr; 569 570 /* header */ 571 tableU16[-2] = (U16) 0; 572 tableU16[-1] = (U16) symbolValue; 573 574 /* Build table */ 575 tableU16[0] = 0; 576 tableU16[1] = 0; /* just in case */ 577 578 /* Build Symbol Transformation Table */ 579 symbolTT[symbolValue].deltaNbBits = 0; 580 symbolTT[symbolValue].deltaFindState = 0; 581 582 return 0; 583 } 584 585 586 static size_t FSE_compress_usingCTable_generic (void* dst, size_t dstSize, 587 const void* src, size_t srcSize, 588 const FSE_CTable* ct, const unsigned fast) 589 { 590 const BYTE* const istart = (const BYTE*) src; 591 const BYTE* const iend = istart + srcSize; 592 const BYTE* ip=iend; 593 594 BIT_CStream_t bitC; 595 FSE_CState_t CState1, CState2; 596 597 /* init */ 598 if (srcSize <= 2) return 0; 599 { size_t const initError = BIT_initCStream(&bitC, dst, dstSize); 600 if (FSE_isError(initError)) return 0; /* not enough space available to write a bitstream */ } 601 602 #define FSE_FLUSHBITS(s) (fast ? BIT_flushBitsFast(s) : BIT_flushBits(s)) 603 604 if (srcSize & 1) { 605 FSE_initCState2(&CState1, ct, *--ip); 606 FSE_initCState2(&CState2, ct, *--ip); 607 FSE_encodeSymbol(&bitC, &CState1, *--ip); 608 FSE_FLUSHBITS(&bitC); 609 } else { 610 FSE_initCState2(&CState2, ct, *--ip); 611 FSE_initCState2(&CState1, ct, *--ip); 612 } 613 614 /* join to mod 4 */ 615 srcSize -= 2; 616 if ((sizeof(bitC.bitContainer)*8 > FSE_MAX_TABLELOG*4+7 ) && (srcSize & 2)) { /* test bit 2 */ 617 FSE_encodeSymbol(&bitC, &CState2, *--ip); 618 FSE_encodeSymbol(&bitC, &CState1, *--ip); 619 FSE_FLUSHBITS(&bitC); 620 } 621 622 /* 2 or 4 encoding per loop */ 623 while ( ip>istart ) { 624 625 FSE_encodeSymbol(&bitC, &CState2, *--ip); 626 627 if (sizeof(bitC.bitContainer)*8 < FSE_MAX_TABLELOG*2+7 ) /* this test must be static */ 628 FSE_FLUSHBITS(&bitC); 629 630 FSE_encodeSymbol(&bitC, &CState1, *--ip); 631 632 if (sizeof(bitC.bitContainer)*8 > FSE_MAX_TABLELOG*4+7 ) { /* this test must be static */ 633 FSE_encodeSymbol(&bitC, &CState2, *--ip); 634 FSE_encodeSymbol(&bitC, &CState1, *--ip); 635 } 636 637 FSE_FLUSHBITS(&bitC); 638 } 639 640 FSE_flushCState(&bitC, &CState2); 641 FSE_flushCState(&bitC, &CState1); 642 return BIT_closeCStream(&bitC); 643 } 644 645 size_t FSE_compress_usingCTable (void* dst, size_t dstSize, 646 const void* src, size_t srcSize, 647 const FSE_CTable* ct) 648 { 649 unsigned const fast = (dstSize >= FSE_BLOCKBOUND(srcSize)); 650 651 if (fast) 652 return FSE_compress_usingCTable_generic(dst, dstSize, src, srcSize, ct, 1); 653 else 654 return FSE_compress_usingCTable_generic(dst, dstSize, src, srcSize, ct, 0); 655 } 656 657 658 size_t FSE_compressBound(size_t size) { return FSE_COMPRESSBOUND(size); } 659 660 #define CHECK_V_F(e, f) size_t const e = f; if (ERR_isError(e)) return e 661 #define CHECK_F(f) { CHECK_V_F(_var_err__, f); } 662 663 /* FSE_compress_wksp() : 664 * Same as FSE_compress2(), but using an externally allocated scratch buffer (`workSpace`). 665 * `wkspSize` size must be `(1<<tableLog)`. 666 */ 667 size_t FSE_compress_wksp (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize) 668 { 669 BYTE* const ostart = (BYTE*) dst; 670 BYTE* op = ostart; 671 BYTE* const oend = ostart + dstSize; 672 673 U32 count[FSE_MAX_SYMBOL_VALUE+1]; 674 S16 norm[FSE_MAX_SYMBOL_VALUE+1]; 675 FSE_CTable* CTable = (FSE_CTable*)workSpace; 676 size_t const CTableSize = FSE_CTABLE_SIZE_U32(tableLog, maxSymbolValue); 677 void* scratchBuffer = (void*)(CTable + CTableSize); 678 size_t const scratchBufferSize = wkspSize - (CTableSize * sizeof(FSE_CTable)); 679 680 /* init conditions */ 681 if (wkspSize < FSE_WKSP_SIZE_U32(tableLog, maxSymbolValue)) return ERROR(tableLog_tooLarge); 682 if (srcSize <= 1) return 0; /* Not compressible */ 683 if (!maxSymbolValue) maxSymbolValue = FSE_MAX_SYMBOL_VALUE; 684 if (!tableLog) tableLog = FSE_DEFAULT_TABLELOG; 685 686 /* Scan input and build symbol stats */ 687 { CHECK_V_F(maxCount, HIST_count_wksp(count, &maxSymbolValue, src, srcSize, (unsigned*)scratchBuffer) ); 688 if (maxCount == srcSize) return 1; /* only a single symbol in src : rle */ 689 if (maxCount == 1) return 0; /* each symbol present maximum once => not compressible */ 690 if (maxCount < (srcSize >> 7)) return 0; /* Heuristic : not compressible enough */ 691 } 692 693 tableLog = FSE_optimalTableLog(tableLog, srcSize, maxSymbolValue); 694 CHECK_F( FSE_normalizeCount(norm, tableLog, count, srcSize, maxSymbolValue) ); 695 696 /* Write table description header */ 697 { CHECK_V_F(nc_err, FSE_writeNCount(op, oend-op, norm, maxSymbolValue, tableLog) ); 698 op += nc_err; 699 } 700 701 /* Compress */ 702 CHECK_F( FSE_buildCTable_wksp(CTable, norm, maxSymbolValue, tableLog, scratchBuffer, scratchBufferSize) ); 703 { CHECK_V_F(cSize, FSE_compress_usingCTable(op, oend - op, src, srcSize, CTable) ); 704 if (cSize == 0) return 0; /* not enough space for compressed data */ 705 op += cSize; 706 } 707 708 /* check compressibility */ 709 if ( (size_t)(op-ostart) >= srcSize-1 ) return 0; 710 711 return op-ostart; 712 } 713 714 typedef struct { 715 FSE_CTable CTable_max[FSE_CTABLE_SIZE_U32(FSE_MAX_TABLELOG, FSE_MAX_SYMBOL_VALUE)]; 716 BYTE scratchBuffer[1 << FSE_MAX_TABLELOG]; 717 } fseWkspMax_t; 718 719 size_t FSE_compress2 (void* dst, size_t dstCapacity, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog) 720 { 721 fseWkspMax_t* scratchBuffer; 722 size_t ret; 723 724 DEBUG_STATIC_ASSERT(sizeof(fseWkspMax_t) >= FSE_WKSP_SIZE_U32(FSE_MAX_TABLELOG, FSE_MAX_SYMBOL_VALUE)); /* compilation failures here means scratchBuffer is not large enough */ 725 726 if (tableLog > FSE_MAX_TABLELOG) 727 return ERROR(tableLog_tooLarge); 728 729 scratchBuffer = ExAllocatePoolWithTag(NonPagedPool, sizeof(fseWkspMax_t), FSEC_ALLOC_TAG); 730 731 if (!scratchBuffer) 732 return 0; 733 734 ret = FSE_compress_wksp(dst, dstCapacity, src, srcSize, maxSymbolValue, tableLog, scratchBuffer, sizeof(fseWkspMax_t)); 735 736 ExFreePool(scratchBuffer); 737 738 return ret; 739 } 740 741 size_t FSE_compress (void* dst, size_t dstCapacity, const void* src, size_t srcSize) 742 { 743 return FSE_compress2(dst, dstCapacity, src, srcSize, FSE_MAX_SYMBOL_VALUE, FSE_DEFAULT_TABLELOG); 744 } 745 746 747 #endif /* FSE_COMMONDEFS_ONLY */ 748