| /* |
| Common functions of Zstd compression library |
| Copyright (C) 2015-2016, Yann Collet. |
| |
| BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) |
| |
| Redistribution and use in source and binary forms, with or without |
| modification, are permitted provided that the following conditions are |
| met: |
| * Redistributions of source code must retain the above copyright |
| notice, this list of conditions and the following disclaimer. |
| * Redistributions in binary form must reproduce the above |
| copyright notice, this list of conditions and the following disclaimer |
| in the documentation and/or other materials provided with the |
| distribution. |
| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| |
| You can contact the author at : |
| - zstd homepage : http://www.zstd.net/ |
| */ |
| |
| |
| /* ************************************* |
| * Dependencies |
| ***************************************/ |
| #include <stdlib.h> |
| #include "mem.h" |
| #include "fse_static.h" /* FSE_MIN_TABLELOG */ |
| #include "error_private.h" |
| #include "zstd.h" /* declaration of ZSTD_isError, ZSTD_getErrorName */ |
| #include "zbuff.h" /* declaration of ZBUFF_isError, ZBUFF_getErrorName */ |
| #include "fse.h" /* declaration of FSE_isError, FSE_getErrorName */ |
| #include "huf.h" /* declaration of HUF_isError, HUF_getErrorName */ |
| |
| |
| /*-**************************************** |
| * ZSTD Error Management |
| ******************************************/ |
| /*! ZSTD_isError() : |
| * tells if a return value is an error code */ |
| unsigned ZSTD_isError(size_t code) { return ERR_isError(code); } |
| |
| /*! ZSTD_getError() : |
| * convert a `size_t` function result into a proper ZSTD_errorCode enum */ |
| ZSTD_ErrorCode ZSTD_getErrorCode(size_t code) { return ERR_getErrorCode(code); } |
| |
| /*! ZSTD_getErrorName() : |
| * provides error code string (useful for debugging) */ |
| const char* ZSTD_getErrorName(size_t code) { return ERR_getErrorName(code); } |
| |
| /*! ZSTD_getErrorName() : |
| * provides error code string (useful for debugging) */ |
| const char* ZSTD_getErrorString(ZSTD_ErrorCode code) { return ERR_getErrorName(code); } |
| |
| |
| /*-**************************************** |
| * FSE Error Management |
| ******************************************/ |
| unsigned FSE_isError(size_t code) { return ERR_isError(code); } |
| |
| const char* FSE_getErrorName(size_t code) { return ERR_getErrorName(code); } |
| |
| |
| /* ************************************************************** |
| * HUF Error Management |
| ****************************************************************/ |
| unsigned HUF_isError(size_t code) { return ERR_isError(code); } |
| |
| const char* HUF_getErrorName(size_t code) { return ERR_getErrorName(code); } |
| |
| |
| /* ************************************************************** |
| * ZBUFF Error Management |
| ****************************************************************/ |
| unsigned ZBUFF_isError(size_t errorCode) { return ERR_isError(errorCode); } |
| |
| const char* ZBUFF_getErrorName(size_t errorCode) { return ERR_getErrorName(errorCode); } |
| |
| |
| /*-************************************************************** |
| * FSE NCount encoding-decoding |
| ****************************************************************/ |
| static short FSE_abs(short a) { return a<0 ? -a : a; } |
| |
| size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr, |
| const void* headerBuffer, size_t hbSize) |
| { |
| const BYTE* const istart = (const BYTE*) headerBuffer; |
| const BYTE* const iend = istart + hbSize; |
| const BYTE* ip = istart; |
| int nbBits; |
| int remaining; |
| int threshold; |
| U32 bitStream; |
| int bitCount; |
| unsigned charnum = 0; |
| int previous0 = 0; |
| |
| if (hbSize < 4) return ERROR(srcSize_wrong); |
| bitStream = MEM_readLE32(ip); |
| nbBits = (bitStream & 0xF) + FSE_MIN_TABLELOG; /* extract tableLog */ |
| if (nbBits > FSE_TABLELOG_ABSOLUTE_MAX) return ERROR(tableLog_tooLarge); |
| bitStream >>= 4; |
| bitCount = 4; |
| *tableLogPtr = nbBits; |
| remaining = (1<<nbBits)+1; |
| threshold = 1<<nbBits; |
| nbBits++; |
| |
| while ((remaining>1) && (charnum<=*maxSVPtr)) { |
| if (previous0) { |
| unsigned n0 = charnum; |
| while ((bitStream & 0xFFFF) == 0xFFFF) { |
| n0+=24; |
| if (ip < iend-5) { |
| ip+=2; |
| bitStream = MEM_readLE32(ip) >> bitCount; |
| } else { |
| bitStream >>= 16; |
| bitCount+=16; |
| } } |
| while ((bitStream & 3) == 3) { |
| n0+=3; |
| bitStream>>=2; |
| bitCount+=2; |
| } |
| n0 += bitStream & 3; |
| bitCount += 2; |
| if (n0 > *maxSVPtr) return ERROR(maxSymbolValue_tooSmall); |
| while (charnum < n0) normalizedCounter[charnum++] = 0; |
| if ((ip <= iend-7) || (ip + (bitCount>>3) <= iend-4)) { |
| ip += bitCount>>3; |
| bitCount &= 7; |
| bitStream = MEM_readLE32(ip) >> bitCount; |
| } |
| else |
| bitStream >>= 2; |
| } |
| { short const max = (short)((2*threshold-1)-remaining); |
| short count; |
| |
| if ((bitStream & (threshold-1)) < (U32)max) { |
| count = (short)(bitStream & (threshold-1)); |
| bitCount += nbBits-1; |
| } else { |
| count = (short)(bitStream & (2*threshold-1)); |
| if (count >= threshold) count -= max; |
| bitCount += nbBits; |
| } |
| |
| count--; /* extra accuracy */ |
| remaining -= FSE_abs(count); |
| normalizedCounter[charnum++] = count; |
| previous0 = !count; |
| while (remaining < threshold) { |
| nbBits--; |
| threshold >>= 1; |
| } |
| |
| if ((ip <= iend-7) || (ip + (bitCount>>3) <= iend-4)) { |
| ip += bitCount>>3; |
| bitCount &= 7; |
| } else { |
| bitCount -= (int)(8 * (iend - 4 - ip)); |
| ip = iend - 4; |
| } |
| bitStream = MEM_readLE32(ip) >> (bitCount & 31); |
| } } |
| if (remaining != 1) return ERROR(GENERIC); |
| *maxSVPtr = charnum-1; |
| |
| ip += (bitCount+7)>>3; |
| if ((size_t)(ip-istart) > hbSize) return ERROR(srcSize_wrong); |
| return ip-istart; |
| } |