1 /* 1 /* 2 * LZ4 - Fast LZ compression algorithm 2 * LZ4 - Fast LZ compression algorithm 3 * Copyright (C) 2011 - 2016, Yann Collet. 3 * Copyright (C) 2011 - 2016, Yann Collet. 4 * BSD 2 - Clause License (http://www.opensour 4 * BSD 2 - Clause License (http://www.opensource.org/licenses/bsd - license.php) 5 * Redistribution and use in source and binary 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that t 6 * modification, are permitted provided that the following conditions are 7 * met: 7 * met: 8 * * Redistributions of source code must 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions a 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials 12 * in the documentation and/or other materials provided with the 13 * distribution. 13 * distribution. 14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT 14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 15 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTI 15 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 16 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCH 16 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 17 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 17 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 18 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIR 18 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 19 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGE 19 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 20 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, S 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE PO 24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * You can contact the author at : 25 * You can contact the author at : 26 * - LZ4 homepage : http://www.lz4.org 26 * - LZ4 homepage : http://www.lz4.org 27 * - LZ4 source repository : https://gith 27 * - LZ4 source repository : https://github.com/lz4/lz4 28 * 28 * 29 * Changed for kernel usage by: 29 * Changed for kernel usage by: 30 * Sven Schmidt <4sschmid@informatik.uni- 30 * Sven Schmidt <4sschmid@informatik.uni-hamburg.de> 31 */ 31 */ 32 32 33 /*-************************************ 33 /*-************************************ 34 * Dependencies 34 * Dependencies 35 **************************************/ 35 **************************************/ 36 #include <linux/lz4.h> 36 #include <linux/lz4.h> 37 #include "lz4defs.h" 37 #include "lz4defs.h" 38 #include <linux/module.h> 38 #include <linux/module.h> 39 #include <linux/kernel.h> 39 #include <linux/kernel.h> 40 #include <linux/unaligned.h> !! 40 #include <asm/unaligned.h> 41 41 42 static const int LZ4_minLength = (MFLIMIT + 1) 42 static const int LZ4_minLength = (MFLIMIT + 1); 43 static const int LZ4_64Klimit = ((64 * KB) + ( 43 static const int LZ4_64Klimit = ((64 * KB) + (MFLIMIT - 1)); 44 44 45 /*-****************************** 45 /*-****************************** 46 * Compression functions 46 * Compression functions 47 ********************************/ 47 ********************************/ 48 static FORCE_INLINE U32 LZ4_hash4( 48 static FORCE_INLINE U32 LZ4_hash4( 49 U32 sequence, 49 U32 sequence, 50 tableType_t const tableType) 50 tableType_t const tableType) 51 { 51 { 52 if (tableType == byU16) 52 if (tableType == byU16) 53 return ((sequence * 2654435761 53 return ((sequence * 2654435761U) 54 >> ((MINMATCH * 8) - ( 54 >> ((MINMATCH * 8) - (LZ4_HASHLOG + 1))); 55 else 55 else 56 return ((sequence * 2654435761 56 return ((sequence * 2654435761U) 57 >> ((MINMATCH * 8) - L 57 >> ((MINMATCH * 8) - LZ4_HASHLOG)); 58 } 58 } 59 59 60 static FORCE_INLINE U32 LZ4_hash5( 60 static FORCE_INLINE U32 LZ4_hash5( 61 U64 sequence, 61 U64 sequence, 62 tableType_t const tableType) 62 tableType_t const tableType) 63 { 63 { 64 const U32 hashLog = (tableType == byU1 64 const U32 hashLog = (tableType == byU16) 65 ? LZ4_HASHLOG + 1 65 ? LZ4_HASHLOG + 1 66 : LZ4_HASHLOG; 66 : LZ4_HASHLOG; 67 67 68 #if LZ4_LITTLE_ENDIAN 68 #if LZ4_LITTLE_ENDIAN 69 static const U64 prime5bytes = 8895235 69 static const U64 prime5bytes = 889523592379ULL; 70 70 71 return (U32)(((sequence << 24) * prime 71 return (U32)(((sequence << 24) * prime5bytes) >> (64 - hashLog)); 72 #else 72 #else 73 static const U64 prime8bytes = 1140071 73 static const U64 prime8bytes = 11400714785074694791ULL; 74 74 75 return (U32)(((sequence >> 24) * prime 75 return (U32)(((sequence >> 24) * prime8bytes) >> (64 - hashLog)); 76 #endif 76 #endif 77 } 77 } 78 78 79 static FORCE_INLINE U32 LZ4_hashPosition( 79 static FORCE_INLINE U32 LZ4_hashPosition( 80 const void *p, 80 const void *p, 81 tableType_t const tableType) 81 tableType_t const tableType) 82 { 82 { 83 #if LZ4_ARCH64 83 #if LZ4_ARCH64 84 if (tableType == byU32) 84 if (tableType == byU32) 85 return LZ4_hash5(LZ4_read_ARCH 85 return LZ4_hash5(LZ4_read_ARCH(p), tableType); 86 #endif 86 #endif 87 87 88 return LZ4_hash4(LZ4_read32(p), tableT 88 return LZ4_hash4(LZ4_read32(p), tableType); 89 } 89 } 90 90 91 static void LZ4_putPositionOnHash( 91 static void LZ4_putPositionOnHash( 92 const BYTE *p, 92 const BYTE *p, 93 U32 h, 93 U32 h, 94 void *tableBase, 94 void *tableBase, 95 tableType_t const tableType, 95 tableType_t const tableType, 96 const BYTE *srcBase) 96 const BYTE *srcBase) 97 { 97 { 98 switch (tableType) { 98 switch (tableType) { 99 case byPtr: 99 case byPtr: 100 { 100 { 101 const BYTE **hashTable = (cons 101 const BYTE **hashTable = (const BYTE **)tableBase; 102 102 103 hashTable[h] = p; 103 hashTable[h] = p; 104 return; 104 return; 105 } 105 } 106 case byU32: 106 case byU32: 107 { 107 { 108 U32 *hashTable = (U32 *) table 108 U32 *hashTable = (U32 *) tableBase; 109 109 110 hashTable[h] = (U32)(p - srcBa 110 hashTable[h] = (U32)(p - srcBase); 111 return; 111 return; 112 } 112 } 113 case byU16: 113 case byU16: 114 { 114 { 115 U16 *hashTable = (U16 *) table 115 U16 *hashTable = (U16 *) tableBase; 116 116 117 hashTable[h] = (U16)(p - srcBa 117 hashTable[h] = (U16)(p - srcBase); 118 return; 118 return; 119 } 119 } 120 } 120 } 121 } 121 } 122 122 123 static FORCE_INLINE void LZ4_putPosition( 123 static FORCE_INLINE void LZ4_putPosition( 124 const BYTE *p, 124 const BYTE *p, 125 void *tableBase, 125 void *tableBase, 126 tableType_t tableType, 126 tableType_t tableType, 127 const BYTE *srcBase) 127 const BYTE *srcBase) 128 { 128 { 129 U32 const h = LZ4_hashPosition(p, tabl 129 U32 const h = LZ4_hashPosition(p, tableType); 130 130 131 LZ4_putPositionOnHash(p, h, tableBase, 131 LZ4_putPositionOnHash(p, h, tableBase, tableType, srcBase); 132 } 132 } 133 133 134 static const BYTE *LZ4_getPositionOnHash( 134 static const BYTE *LZ4_getPositionOnHash( 135 U32 h, 135 U32 h, 136 void *tableBase, 136 void *tableBase, 137 tableType_t tableType, 137 tableType_t tableType, 138 const BYTE *srcBase) 138 const BYTE *srcBase) 139 { 139 { 140 if (tableType == byPtr) { 140 if (tableType == byPtr) { 141 const BYTE **hashTable = (cons 141 const BYTE **hashTable = (const BYTE **) tableBase; 142 142 143 return hashTable[h]; 143 return hashTable[h]; 144 } 144 } 145 145 146 if (tableType == byU32) { 146 if (tableType == byU32) { 147 const U32 * const hashTable = 147 const U32 * const hashTable = (U32 *) tableBase; 148 148 149 return hashTable[h] + srcBase; 149 return hashTable[h] + srcBase; 150 } 150 } 151 151 152 { 152 { 153 /* default, to ensure a return 153 /* default, to ensure a return */ 154 const U16 * const hashTable = 154 const U16 * const hashTable = (U16 *) tableBase; 155 155 156 return hashTable[h] + srcBase; 156 return hashTable[h] + srcBase; 157 } 157 } 158 } 158 } 159 159 160 static FORCE_INLINE const BYTE *LZ4_getPositio 160 static FORCE_INLINE const BYTE *LZ4_getPosition( 161 const BYTE *p, 161 const BYTE *p, 162 void *tableBase, 162 void *tableBase, 163 tableType_t tableType, 163 tableType_t tableType, 164 const BYTE *srcBase) 164 const BYTE *srcBase) 165 { 165 { 166 U32 const h = LZ4_hashPosition(p, tabl 166 U32 const h = LZ4_hashPosition(p, tableType); 167 167 168 return LZ4_getPositionOnHash(h, tableB 168 return LZ4_getPositionOnHash(h, tableBase, tableType, srcBase); 169 } 169 } 170 170 171 171 172 /* 172 /* 173 * LZ4_compress_generic() : 173 * LZ4_compress_generic() : 174 * inlined, to ensure branches are decided at 174 * inlined, to ensure branches are decided at compilation time 175 */ 175 */ 176 static FORCE_INLINE int LZ4_compress_generic( 176 static FORCE_INLINE int LZ4_compress_generic( 177 LZ4_stream_t_internal * const dictPtr, 177 LZ4_stream_t_internal * const dictPtr, 178 const char * const source, 178 const char * const source, 179 char * const dest, 179 char * const dest, 180 const int inputSize, 180 const int inputSize, 181 const int maxOutputSize, 181 const int maxOutputSize, 182 const limitedOutput_directive outputLi 182 const limitedOutput_directive outputLimited, 183 const tableType_t tableType, 183 const tableType_t tableType, 184 const dict_directive dict, 184 const dict_directive dict, 185 const dictIssue_directive dictIssue, 185 const dictIssue_directive dictIssue, 186 const U32 acceleration) 186 const U32 acceleration) 187 { 187 { 188 const BYTE *ip = (const BYTE *) source 188 const BYTE *ip = (const BYTE *) source; 189 const BYTE *base; 189 const BYTE *base; 190 const BYTE *lowLimit; 190 const BYTE *lowLimit; 191 const BYTE * const lowRefLimit = ip - 191 const BYTE * const lowRefLimit = ip - dictPtr->dictSize; 192 const BYTE * const dictionary = dictPt 192 const BYTE * const dictionary = dictPtr->dictionary; 193 const BYTE * const dictEnd = dictionar 193 const BYTE * const dictEnd = dictionary + dictPtr->dictSize; 194 const size_t dictDelta = dictEnd - (co 194 const size_t dictDelta = dictEnd - (const BYTE *)source; 195 const BYTE *anchor = (const BYTE *) so 195 const BYTE *anchor = (const BYTE *) source; 196 const BYTE * const iend = ip + inputSi 196 const BYTE * const iend = ip + inputSize; 197 const BYTE * const mflimit = iend - MF 197 const BYTE * const mflimit = iend - MFLIMIT; 198 const BYTE * const matchlimit = iend - 198 const BYTE * const matchlimit = iend - LASTLITERALS; 199 199 200 BYTE *op = (BYTE *) dest; 200 BYTE *op = (BYTE *) dest; 201 BYTE * const olimit = op + maxOutputSi 201 BYTE * const olimit = op + maxOutputSize; 202 202 203 U32 forwardH; 203 U32 forwardH; 204 size_t refDelta = 0; 204 size_t refDelta = 0; 205 205 206 /* Init conditions */ 206 /* Init conditions */ 207 if ((U32)inputSize > (U32)LZ4_MAX_INPU 207 if ((U32)inputSize > (U32)LZ4_MAX_INPUT_SIZE) { 208 /* Unsupported inputSize, too 208 /* Unsupported inputSize, too large (or negative) */ 209 return 0; 209 return 0; 210 } 210 } 211 211 212 switch (dict) { 212 switch (dict) { 213 case noDict: 213 case noDict: 214 default: 214 default: 215 base = (const BYTE *)source; 215 base = (const BYTE *)source; 216 lowLimit = (const BYTE *)sourc 216 lowLimit = (const BYTE *)source; 217 break; 217 break; 218 case withPrefix64k: 218 case withPrefix64k: 219 base = (const BYTE *)source - 219 base = (const BYTE *)source - dictPtr->currentOffset; 220 lowLimit = (const BYTE *)sourc 220 lowLimit = (const BYTE *)source - dictPtr->dictSize; 221 break; 221 break; 222 case usingExtDict: 222 case usingExtDict: 223 base = (const BYTE *)source - 223 base = (const BYTE *)source - dictPtr->currentOffset; 224 lowLimit = (const BYTE *)sourc 224 lowLimit = (const BYTE *)source; 225 break; 225 break; 226 } 226 } 227 227 228 if ((tableType == byU16) 228 if ((tableType == byU16) 229 && (inputSize >= LZ4_64Klimit) 229 && (inputSize >= LZ4_64Klimit)) { 230 /* Size too large (not within 230 /* Size too large (not within 64K limit) */ 231 return 0; 231 return 0; 232 } 232 } 233 233 234 if (inputSize < LZ4_minLength) { 234 if (inputSize < LZ4_minLength) { 235 /* Input too small, no compres 235 /* Input too small, no compression (all literals) */ 236 goto _last_literals; 236 goto _last_literals; 237 } 237 } 238 238 239 /* First Byte */ 239 /* First Byte */ 240 LZ4_putPosition(ip, dictPtr->hashTable 240 LZ4_putPosition(ip, dictPtr->hashTable, tableType, base); 241 ip++; 241 ip++; 242 forwardH = LZ4_hashPosition(ip, tableT 242 forwardH = LZ4_hashPosition(ip, tableType); 243 243 244 /* Main Loop */ 244 /* Main Loop */ 245 for ( ; ; ) { 245 for ( ; ; ) { 246 const BYTE *match; 246 const BYTE *match; 247 BYTE *token; 247 BYTE *token; 248 248 249 /* Find a match */ 249 /* Find a match */ 250 { 250 { 251 const BYTE *forwardIp 251 const BYTE *forwardIp = ip; 252 unsigned int step = 1; 252 unsigned int step = 1; 253 unsigned int searchMat 253 unsigned int searchMatchNb = acceleration << LZ4_SKIPTRIGGER; 254 254 255 do { 255 do { 256 U32 const h = 256 U32 const h = forwardH; 257 257 258 ip = forwardIp 258 ip = forwardIp; 259 forwardIp += s 259 forwardIp += step; 260 step = (search 260 step = (searchMatchNb++ >> LZ4_SKIPTRIGGER); 261 261 262 if (unlikely(f 262 if (unlikely(forwardIp > mflimit)) 263 goto _ 263 goto _last_literals; 264 264 265 match = LZ4_ge 265 match = LZ4_getPositionOnHash(h, 266 dictPt 266 dictPtr->hashTable, 267 tableT 267 tableType, base); 268 268 269 if (dict == us 269 if (dict == usingExtDict) { 270 if (ma 270 if (match < (const BYTE *)source) { 271 271 refDelta = dictDelta; 272 272 lowLimit = dictionary; 273 } else 273 } else { 274 274 refDelta = 0; 275 275 lowLimit = (const BYTE *)source; 276 } } 276 } } 277 277 278 forwardH = LZ4 278 forwardH = LZ4_hashPosition(forwardIp, 279 tableT 279 tableType); 280 280 281 LZ4_putPositio 281 LZ4_putPositionOnHash(ip, h, dictPtr->hashTable, 282 tableT 282 tableType, base); 283 } while (((dictIssue = 283 } while (((dictIssue == dictSmall) 284 ? (mat 284 ? (match < lowRefLimit) 285 : 0) 285 : 0) 286 || ((tableType 286 || ((tableType == byU16) 287 ? 0 287 ? 0 288 : (mat 288 : (match + MAX_DISTANCE < ip)) 289 || (LZ4_read32 289 || (LZ4_read32(match + refDelta) 290 != LZ4 290 != LZ4_read32(ip))); 291 } 291 } 292 292 293 /* Catch up */ 293 /* Catch up */ 294 while (((ip > anchor) & (match 294 while (((ip > anchor) & (match + refDelta > lowLimit)) 295 && (unlikely(i 295 && (unlikely(ip[-1] == match[refDelta - 1]))) { 296 ip--; 296 ip--; 297 match--; 297 match--; 298 } 298 } 299 299 300 /* Encode Literals */ 300 /* Encode Literals */ 301 { 301 { 302 unsigned const int lit 302 unsigned const int litLength = (unsigned int)(ip - anchor); 303 303 304 token = op++; 304 token = op++; 305 305 306 if ((outputLimited) && 306 if ((outputLimited) && 307 /* Check outpu 307 /* Check output buffer overflow */ 308 (unlikely(op + 308 (unlikely(op + litLength + 309 (2 + 1 309 (2 + 1 + LASTLITERALS) + 310 (litLe 310 (litLength / 255) > olimit))) 311 return 0; 311 return 0; 312 312 313 if (litLength >= RUN_M 313 if (litLength >= RUN_MASK) { 314 int len = (int 314 int len = (int)litLength - RUN_MASK; 315 315 316 *token = (RUN_ 316 *token = (RUN_MASK << ML_BITS); 317 317 318 for (; len >= 318 for (; len >= 255; len -= 255) 319 *op++ 319 *op++ = 255; 320 *op++ = (BYTE) 320 *op++ = (BYTE)len; 321 } else 321 } else 322 *token = (BYTE 322 *token = (BYTE)(litLength << ML_BITS); 323 323 324 /* Copy Literals */ 324 /* Copy Literals */ 325 LZ4_wildCopy(op, ancho 325 LZ4_wildCopy(op, anchor, op + litLength); 326 op += litLength; 326 op += litLength; 327 } 327 } 328 328 329 _next_match: 329 _next_match: 330 /* Encode Offset */ 330 /* Encode Offset */ 331 LZ4_writeLE16(op, (U16)(ip - m 331 LZ4_writeLE16(op, (U16)(ip - match)); 332 op += 2; 332 op += 2; 333 333 334 /* Encode MatchLength */ 334 /* Encode MatchLength */ 335 { 335 { 336 unsigned int matchCode 336 unsigned int matchCode; 337 337 338 if ((dict == usingExtD 338 if ((dict == usingExtDict) 339 && (lowLimit = 339 && (lowLimit == dictionary)) { 340 const BYTE *li 340 const BYTE *limit; 341 341 342 match += refDe 342 match += refDelta; 343 limit = ip + ( 343 limit = ip + (dictEnd - match); 344 344 345 if (limit > ma 345 if (limit > matchlimit) 346 limit 346 limit = matchlimit; 347 347 348 matchCode = LZ 348 matchCode = LZ4_count(ip + MINMATCH, 349 match 349 match + MINMATCH, limit); 350 350 351 ip += MINMATCH 351 ip += MINMATCH + matchCode; 352 352 353 if (ip == limi 353 if (ip == limit) { 354 unsign 354 unsigned const int more = LZ4_count(ip, 355 355 (const BYTE *)source, 356 356 matchlimit); 357 357 358 matchC 358 matchCode += more; 359 ip += 359 ip += more; 360 } 360 } 361 } else { 361 } else { 362 matchCode = LZ 362 matchCode = LZ4_count(ip + MINMATCH, 363 match 363 match + MINMATCH, matchlimit); 364 ip += MINMATCH 364 ip += MINMATCH + matchCode; 365 } 365 } 366 366 367 if (outputLimited && 367 if (outputLimited && 368 /* Check outpu 368 /* Check output buffer overflow */ 369 (unlikely(op + 369 (unlikely(op + 370 (1 + L 370 (1 + LASTLITERALS) + 371 (match 371 (matchCode >> 8) > olimit))) 372 return 0; 372 return 0; 373 373 374 if (matchCode >= ML_MA 374 if (matchCode >= ML_MASK) { 375 *token += ML_M 375 *token += ML_MASK; 376 matchCode -= M 376 matchCode -= ML_MASK; 377 LZ4_write32(op 377 LZ4_write32(op, 0xFFFFFFFF); 378 378 379 while (matchCo 379 while (matchCode >= 4 * 255) { 380 op += 380 op += 4; 381 LZ4_wr 381 LZ4_write32(op, 0xFFFFFFFF); 382 matchC 382 matchCode -= 4 * 255; 383 } 383 } 384 384 385 op += matchCod 385 op += matchCode / 255; 386 *op++ = (BYTE) 386 *op++ = (BYTE)(matchCode % 255); 387 } else 387 } else 388 *token += (BYT 388 *token += (BYTE)(matchCode); 389 } 389 } 390 390 391 anchor = ip; 391 anchor = ip; 392 392 393 /* Test end of chunk */ 393 /* Test end of chunk */ 394 if (ip > mflimit) 394 if (ip > mflimit) 395 break; 395 break; 396 396 397 /* Fill table */ 397 /* Fill table */ 398 LZ4_putPosition(ip - 2, dictPt 398 LZ4_putPosition(ip - 2, dictPtr->hashTable, tableType, base); 399 399 400 /* Test next position */ 400 /* Test next position */ 401 match = LZ4_getPosition(ip, di 401 match = LZ4_getPosition(ip, dictPtr->hashTable, 402 tableType, base); 402 tableType, base); 403 403 404 if (dict == usingExtDict) { 404 if (dict == usingExtDict) { 405 if (match < (const BYT 405 if (match < (const BYTE *)source) { 406 refDelta = dic 406 refDelta = dictDelta; 407 lowLimit = dic 407 lowLimit = dictionary; 408 } else { 408 } else { 409 refDelta = 0; 409 refDelta = 0; 410 lowLimit = (co 410 lowLimit = (const BYTE *)source; 411 } 411 } 412 } 412 } 413 413 414 LZ4_putPosition(ip, dictPtr->h 414 LZ4_putPosition(ip, dictPtr->hashTable, tableType, base); 415 415 416 if (((dictIssue == dictSmall) 416 if (((dictIssue == dictSmall) ? (match >= lowRefLimit) : 1) 417 && (match + MAX_DISTAN 417 && (match + MAX_DISTANCE >= ip) 418 && (LZ4_read32(match + 418 && (LZ4_read32(match + refDelta) == LZ4_read32(ip))) { 419 token = op++; 419 token = op++; 420 *token = 0; 420 *token = 0; 421 goto _next_match; 421 goto _next_match; 422 } 422 } 423 423 424 /* Prepare next loop */ 424 /* Prepare next loop */ 425 forwardH = LZ4_hashPosition(++ 425 forwardH = LZ4_hashPosition(++ip, tableType); 426 } 426 } 427 427 428 _last_literals: 428 _last_literals: 429 /* Encode Last Literals */ 429 /* Encode Last Literals */ 430 { 430 { 431 size_t const lastRun = (size_t 431 size_t const lastRun = (size_t)(iend - anchor); 432 432 433 if ((outputLimited) && 433 if ((outputLimited) && 434 /* Check output buffer 434 /* Check output buffer overflow */ 435 ((op - (BYTE *)dest) + 435 ((op - (BYTE *)dest) + lastRun + 1 + 436 ((lastRun + 255 - RUN_ 436 ((lastRun + 255 - RUN_MASK) / 255) > (U32)maxOutputSize)) 437 return 0; 437 return 0; 438 438 439 if (lastRun >= RUN_MASK) { 439 if (lastRun >= RUN_MASK) { 440 size_t accumulator = l 440 size_t accumulator = lastRun - RUN_MASK; 441 *op++ = RUN_MASK << ML 441 *op++ = RUN_MASK << ML_BITS; 442 for (; accumulator >= 442 for (; accumulator >= 255; accumulator -= 255) 443 *op++ = 255; 443 *op++ = 255; 444 *op++ = (BYTE) accumul 444 *op++ = (BYTE) accumulator; 445 } else { 445 } else { 446 *op++ = (BYTE)(lastRun 446 *op++ = (BYTE)(lastRun << ML_BITS); 447 } 447 } 448 448 449 LZ4_memcpy(op, anchor, lastRun 449 LZ4_memcpy(op, anchor, lastRun); 450 450 451 op += lastRun; 451 op += lastRun; 452 } 452 } 453 453 454 /* End */ 454 /* End */ 455 return (int) (((char *)op) - dest); 455 return (int) (((char *)op) - dest); 456 } 456 } 457 457 458 static int LZ4_compress_fast_extState( 458 static int LZ4_compress_fast_extState( 459 void *state, 459 void *state, 460 const char *source, 460 const char *source, 461 char *dest, 461 char *dest, 462 int inputSize, 462 int inputSize, 463 int maxOutputSize, 463 int maxOutputSize, 464 int acceleration) 464 int acceleration) 465 { 465 { 466 LZ4_stream_t_internal *ctx = &((LZ4_st 466 LZ4_stream_t_internal *ctx = &((LZ4_stream_t *)state)->internal_donotuse; 467 #if LZ4_ARCH64 467 #if LZ4_ARCH64 468 const tableType_t tableType = byU32; 468 const tableType_t tableType = byU32; 469 #else 469 #else 470 const tableType_t tableType = byPtr; 470 const tableType_t tableType = byPtr; 471 #endif 471 #endif 472 472 473 LZ4_resetStream((LZ4_stream_t *)state) 473 LZ4_resetStream((LZ4_stream_t *)state); 474 474 475 if (acceleration < 1) 475 if (acceleration < 1) 476 acceleration = LZ4_ACCELERATIO 476 acceleration = LZ4_ACCELERATION_DEFAULT; 477 477 478 if (maxOutputSize >= LZ4_COMPRESSBOUND 478 if (maxOutputSize >= LZ4_COMPRESSBOUND(inputSize)) { 479 if (inputSize < LZ4_64Klimit) 479 if (inputSize < LZ4_64Klimit) 480 return LZ4_compress_ge 480 return LZ4_compress_generic(ctx, source, 481 dest, inputSiz 481 dest, inputSize, 0, 482 noLimit, byU16 482 noLimit, byU16, noDict, 483 noDictIssue, a 483 noDictIssue, acceleration); 484 else 484 else 485 return LZ4_compress_ge 485 return LZ4_compress_generic(ctx, source, 486 dest, inputSiz 486 dest, inputSize, 0, 487 noLimit, table 487 noLimit, tableType, noDict, 488 noDictIssue, a 488 noDictIssue, acceleration); 489 } else { 489 } else { 490 if (inputSize < LZ4_64Klimit) 490 if (inputSize < LZ4_64Klimit) 491 return LZ4_compress_ge 491 return LZ4_compress_generic(ctx, source, 492 dest, inputSiz 492 dest, inputSize, 493 maxOutputSize, 493 maxOutputSize, limitedOutput, byU16, noDict, 494 noDictIssue, a 494 noDictIssue, acceleration); 495 else 495 else 496 return LZ4_compress_ge 496 return LZ4_compress_generic(ctx, source, 497 dest, inputSiz 497 dest, inputSize, 498 maxOutputSize, 498 maxOutputSize, limitedOutput, tableType, noDict, 499 noDictIssue, a 499 noDictIssue, acceleration); 500 } 500 } 501 } 501 } 502 502 503 int LZ4_compress_fast(const char *source, char 503 int LZ4_compress_fast(const char *source, char *dest, int inputSize, 504 int maxOutputSize, int acceleration, v 504 int maxOutputSize, int acceleration, void *wrkmem) 505 { 505 { 506 return LZ4_compress_fast_extState(wrkm 506 return LZ4_compress_fast_extState(wrkmem, source, dest, inputSize, 507 maxOutputSize, acceleration); 507 maxOutputSize, acceleration); 508 } 508 } 509 EXPORT_SYMBOL(LZ4_compress_fast); 509 EXPORT_SYMBOL(LZ4_compress_fast); 510 510 511 int LZ4_compress_default(const char *source, c 511 int LZ4_compress_default(const char *source, char *dest, int inputSize, 512 int maxOutputSize, void *wrkmem) 512 int maxOutputSize, void *wrkmem) 513 { 513 { 514 return LZ4_compress_fast(source, dest, 514 return LZ4_compress_fast(source, dest, inputSize, 515 maxOutputSize, LZ4_ACCELERATIO 515 maxOutputSize, LZ4_ACCELERATION_DEFAULT, wrkmem); 516 } 516 } 517 EXPORT_SYMBOL(LZ4_compress_default); 517 EXPORT_SYMBOL(LZ4_compress_default); 518 518 519 /*-****************************** 519 /*-****************************** 520 * *_destSize() variant 520 * *_destSize() variant 521 ********************************/ 521 ********************************/ 522 static int LZ4_compress_destSize_generic( 522 static int LZ4_compress_destSize_generic( 523 LZ4_stream_t_internal * const ctx, 523 LZ4_stream_t_internal * const ctx, 524 const char * const src, 524 const char * const src, 525 char * const dst, 525 char * const dst, 526 int * const srcSizePtr, 526 int * const srcSizePtr, 527 const int targetDstSize, 527 const int targetDstSize, 528 const tableType_t tableType) 528 const tableType_t tableType) 529 { 529 { 530 const BYTE *ip = (const BYTE *) src; 530 const BYTE *ip = (const BYTE *) src; 531 const BYTE *base = (const BYTE *) src; 531 const BYTE *base = (const BYTE *) src; 532 const BYTE *lowLimit = (const BYTE *) 532 const BYTE *lowLimit = (const BYTE *) src; 533 const BYTE *anchor = ip; 533 const BYTE *anchor = ip; 534 const BYTE * const iend = ip + *srcSiz 534 const BYTE * const iend = ip + *srcSizePtr; 535 const BYTE * const mflimit = iend - MF 535 const BYTE * const mflimit = iend - MFLIMIT; 536 const BYTE * const matchlimit = iend - 536 const BYTE * const matchlimit = iend - LASTLITERALS; 537 537 538 BYTE *op = (BYTE *) dst; 538 BYTE *op = (BYTE *) dst; 539 BYTE * const oend = op + targetDstSize 539 BYTE * const oend = op + targetDstSize; 540 BYTE * const oMaxLit = op + targetDstS 540 BYTE * const oMaxLit = op + targetDstSize - 2 /* offset */ 541 - 8 /* because 8 + MINMATCH == 541 - 8 /* because 8 + MINMATCH == MFLIMIT */ - 1 /* token */; 542 BYTE * const oMaxMatch = op + targetDs 542 BYTE * const oMaxMatch = op + targetDstSize 543 - (LASTLITERALS + 1 /* token * 543 - (LASTLITERALS + 1 /* token */); 544 BYTE * const oMaxSeq = oMaxLit - 1 /* 544 BYTE * const oMaxSeq = oMaxLit - 1 /* token */; 545 545 546 U32 forwardH; 546 U32 forwardH; 547 547 548 /* Init conditions */ 548 /* Init conditions */ 549 /* Impossible to store anything */ 549 /* Impossible to store anything */ 550 if (targetDstSize < 1) 550 if (targetDstSize < 1) 551 return 0; 551 return 0; 552 /* Unsupported input size, too large ( 552 /* Unsupported input size, too large (or negative) */ 553 if ((U32)*srcSizePtr > (U32)LZ4_MAX_IN 553 if ((U32)*srcSizePtr > (U32)LZ4_MAX_INPUT_SIZE) 554 return 0; 554 return 0; 555 /* Size too large (not within 64K limi 555 /* Size too large (not within 64K limit) */ 556 if ((tableType == byU16) && (*srcSizeP 556 if ((tableType == byU16) && (*srcSizePtr >= LZ4_64Klimit)) 557 return 0; 557 return 0; 558 /* Input too small, no compression (al 558 /* Input too small, no compression (all literals) */ 559 if (*srcSizePtr < LZ4_minLength) 559 if (*srcSizePtr < LZ4_minLength) 560 goto _last_literals; 560 goto _last_literals; 561 561 562 /* First Byte */ 562 /* First Byte */ 563 *srcSizePtr = 0; 563 *srcSizePtr = 0; 564 LZ4_putPosition(ip, ctx->hashTable, ta 564 LZ4_putPosition(ip, ctx->hashTable, tableType, base); 565 ip++; forwardH = LZ4_hashPosition(ip, 565 ip++; forwardH = LZ4_hashPosition(ip, tableType); 566 566 567 /* Main Loop */ 567 /* Main Loop */ 568 for ( ; ; ) { 568 for ( ; ; ) { 569 const BYTE *match; 569 const BYTE *match; 570 BYTE *token; 570 BYTE *token; 571 571 572 /* Find a match */ 572 /* Find a match */ 573 { 573 { 574 const BYTE *forwardIp 574 const BYTE *forwardIp = ip; 575 unsigned int step = 1; 575 unsigned int step = 1; 576 unsigned int searchMat 576 unsigned int searchMatchNb = 1 << LZ4_SKIPTRIGGER; 577 577 578 do { 578 do { 579 U32 h = forwar 579 U32 h = forwardH; 580 580 581 ip = forwardIp 581 ip = forwardIp; 582 forwardIp += s 582 forwardIp += step; 583 step = (search 583 step = (searchMatchNb++ >> LZ4_SKIPTRIGGER); 584 584 585 if (unlikely(f 585 if (unlikely(forwardIp > mflimit)) 586 goto _ 586 goto _last_literals; 587 587 588 match = LZ4_ge 588 match = LZ4_getPositionOnHash(h, ctx->hashTable, 589 tableT 589 tableType, base); 590 forwardH = LZ4 590 forwardH = LZ4_hashPosition(forwardIp, 591 tableT 591 tableType); 592 LZ4_putPositio 592 LZ4_putPositionOnHash(ip, h, 593 ctx->h 593 ctx->hashTable, tableType, 594 base); 594 base); 595 595 596 } while (((tableType = 596 } while (((tableType == byU16) 597 ? 0 597 ? 0 598 : (match + MAX 598 : (match + MAX_DISTANCE < ip)) 599 || (LZ4_read32 599 || (LZ4_read32(match) != LZ4_read32(ip))); 600 } 600 } 601 601 602 /* Catch up */ 602 /* Catch up */ 603 while ((ip > anchor) 603 while ((ip > anchor) 604 && (match > lowLimit) 604 && (match > lowLimit) 605 && (unlikely(ip[-1] == 605 && (unlikely(ip[-1] == match[-1]))) { 606 ip--; 606 ip--; 607 match--; 607 match--; 608 } 608 } 609 609 610 /* Encode Literal length */ 610 /* Encode Literal length */ 611 { 611 { 612 unsigned int litLength 612 unsigned int litLength = (unsigned int)(ip - anchor); 613 613 614 token = op++; 614 token = op++; 615 if (op + ((litLength + 615 if (op + ((litLength + 240) / 255) 616 + litLength > 616 + litLength > oMaxLit) { 617 /* Not enough 617 /* Not enough space for a last match */ 618 op--; 618 op--; 619 goto _last_lit 619 goto _last_literals; 620 } 620 } 621 if (litLength >= RUN_M 621 if (litLength >= RUN_MASK) { 622 unsigned int l 622 unsigned int len = litLength - RUN_MASK; 623 *token = (RUN_ 623 *token = (RUN_MASK<<ML_BITS); 624 for (; len >= 624 for (; len >= 255; len -= 255) 625 *op++ 625 *op++ = 255; 626 *op++ = (BYTE) 626 *op++ = (BYTE)len; 627 } else 627 } else 628 *token = (BYTE 628 *token = (BYTE)(litLength << ML_BITS); 629 629 630 /* Copy Literals */ 630 /* Copy Literals */ 631 LZ4_wildCopy(op, ancho 631 LZ4_wildCopy(op, anchor, op + litLength); 632 op += litLength; 632 op += litLength; 633 } 633 } 634 634 635 _next_match: 635 _next_match: 636 /* Encode Offset */ 636 /* Encode Offset */ 637 LZ4_writeLE16(op, (U16)(ip - m 637 LZ4_writeLE16(op, (U16)(ip - match)); op += 2; 638 638 639 /* Encode MatchLength */ 639 /* Encode MatchLength */ 640 { 640 { 641 size_t matchLength = L 641 size_t matchLength = LZ4_count(ip + MINMATCH, 642 match + MINMATCH, matc 642 match + MINMATCH, matchlimit); 643 643 644 if (op + ((matchLength 644 if (op + ((matchLength + 240)/255) > oMaxMatch) { 645 /* Match descr 645 /* Match description too long : reduce it */ 646 matchLength = 646 matchLength = (15 - 1) + (oMaxMatch - op) * 255; 647 } 647 } 648 ip += MINMATCH + match 648 ip += MINMATCH + matchLength; 649 649 650 if (matchLength >= ML_ 650 if (matchLength >= ML_MASK) { 651 *token += ML_M 651 *token += ML_MASK; 652 matchLength -= 652 matchLength -= ML_MASK; 653 while (matchLe 653 while (matchLength >= 255) { 654 matchL 654 matchLength -= 255; 655 *op++ 655 *op++ = 255; 656 } 656 } 657 *op++ = (BYTE) 657 *op++ = (BYTE)matchLength; 658 } else 658 } else 659 *token += (BYT 659 *token += (BYTE)(matchLength); 660 } 660 } 661 661 662 anchor = ip; 662 anchor = ip; 663 663 664 /* Test end of block */ 664 /* Test end of block */ 665 if (ip > mflimit) 665 if (ip > mflimit) 666 break; 666 break; 667 if (op > oMaxSeq) 667 if (op > oMaxSeq) 668 break; 668 break; 669 669 670 /* Fill table */ 670 /* Fill table */ 671 LZ4_putPosition(ip - 2, ctx->h 671 LZ4_putPosition(ip - 2, ctx->hashTable, tableType, base); 672 672 673 /* Test next position */ 673 /* Test next position */ 674 match = LZ4_getPosition(ip, ct 674 match = LZ4_getPosition(ip, ctx->hashTable, tableType, base); 675 LZ4_putPosition(ip, ctx->hashT 675 LZ4_putPosition(ip, ctx->hashTable, tableType, base); 676 676 677 if ((match + MAX_DISTANCE >= i 677 if ((match + MAX_DISTANCE >= ip) 678 && (LZ4_read32(match) 678 && (LZ4_read32(match) == LZ4_read32(ip))) { 679 token = op++; *token = 679 token = op++; *token = 0; 680 goto _next_match; 680 goto _next_match; 681 } 681 } 682 682 683 /* Prepare next loop */ 683 /* Prepare next loop */ 684 forwardH = LZ4_hashPosition(++ 684 forwardH = LZ4_hashPosition(++ip, tableType); 685 } 685 } 686 686 687 _last_literals: 687 _last_literals: 688 /* Encode Last Literals */ 688 /* Encode Last Literals */ 689 { 689 { 690 size_t lastRunSize = (size_t)( 690 size_t lastRunSize = (size_t)(iend - anchor); 691 691 692 if (op + 1 /* token */ 692 if (op + 1 /* token */ 693 + ((lastRunSize + 240) 693 + ((lastRunSize + 240) / 255) /* litLength */ 694 + lastRunSize /* liter 694 + lastRunSize /* literals */ > oend) { 695 /* adapt lastRunSize t 695 /* adapt lastRunSize to fill 'dst' */ 696 lastRunSize = (oen 696 lastRunSize = (oend - op) - 1; 697 lastRunSize -= (lastRu 697 lastRunSize -= (lastRunSize + 240) / 255; 698 } 698 } 699 ip = anchor + lastRunSize; 699 ip = anchor + lastRunSize; 700 700 701 if (lastRunSize >= RUN_MASK) { 701 if (lastRunSize >= RUN_MASK) { 702 size_t accumulator = l 702 size_t accumulator = lastRunSize - RUN_MASK; 703 703 704 *op++ = RUN_MASK << ML 704 *op++ = RUN_MASK << ML_BITS; 705 for (; accumulator >= 705 for (; accumulator >= 255; accumulator -= 255) 706 *op++ = 255; 706 *op++ = 255; 707 *op++ = (BYTE) accumul 707 *op++ = (BYTE) accumulator; 708 } else { 708 } else { 709 *op++ = (BYTE)(lastRun 709 *op++ = (BYTE)(lastRunSize<<ML_BITS); 710 } 710 } 711 LZ4_memcpy(op, anchor, lastRun 711 LZ4_memcpy(op, anchor, lastRunSize); 712 op += lastRunSize; 712 op += lastRunSize; 713 } 713 } 714 714 715 /* End */ 715 /* End */ 716 *srcSizePtr = (int) (((const char *)ip 716 *srcSizePtr = (int) (((const char *)ip) - src); 717 return (int) (((char *)op) - dst); 717 return (int) (((char *)op) - dst); 718 } 718 } 719 719 720 static int LZ4_compress_destSize_extState( 720 static int LZ4_compress_destSize_extState( 721 LZ4_stream_t *state, 721 LZ4_stream_t *state, 722 const char *src, 722 const char *src, 723 char *dst, 723 char *dst, 724 int *srcSizePtr, 724 int *srcSizePtr, 725 int targetDstSize) 725 int targetDstSize) 726 { 726 { 727 #if LZ4_ARCH64 727 #if LZ4_ARCH64 728 const tableType_t tableType = byU32; 728 const tableType_t tableType = byU32; 729 #else 729 #else 730 const tableType_t tableType = byPtr; 730 const tableType_t tableType = byPtr; 731 #endif 731 #endif 732 732 733 LZ4_resetStream(state); 733 LZ4_resetStream(state); 734 734 735 if (targetDstSize >= LZ4_COMPRESSBOUND 735 if (targetDstSize >= LZ4_COMPRESSBOUND(*srcSizePtr)) { 736 /* compression success is guar 736 /* compression success is guaranteed */ 737 return LZ4_compress_fast_extSt 737 return LZ4_compress_fast_extState( 738 state, src, dst, *srcS 738 state, src, dst, *srcSizePtr, 739 targetDstSize, 1); 739 targetDstSize, 1); 740 } else { 740 } else { 741 if (*srcSizePtr < LZ4_64Klimit 741 if (*srcSizePtr < LZ4_64Klimit) 742 return LZ4_compress_de 742 return LZ4_compress_destSize_generic( 743 &state->intern 743 &state->internal_donotuse, 744 src, dst, srcS 744 src, dst, srcSizePtr, 745 targetDstSize, 745 targetDstSize, byU16); 746 else 746 else 747 return LZ4_compress_de 747 return LZ4_compress_destSize_generic( 748 &state->intern 748 &state->internal_donotuse, 749 src, dst, srcS 749 src, dst, srcSizePtr, 750 targetDstSize, 750 targetDstSize, tableType); 751 } 751 } 752 } 752 } 753 753 754 754 755 int LZ4_compress_destSize( 755 int LZ4_compress_destSize( 756 const char *src, 756 const char *src, 757 char *dst, 757 char *dst, 758 int *srcSizePtr, 758 int *srcSizePtr, 759 int targetDstSize, 759 int targetDstSize, 760 void *wrkmem) 760 void *wrkmem) 761 { 761 { 762 return LZ4_compress_destSize_extState( 762 return LZ4_compress_destSize_extState(wrkmem, src, dst, srcSizePtr, 763 targetDstSize); 763 targetDstSize); 764 } 764 } 765 EXPORT_SYMBOL(LZ4_compress_destSize); 765 EXPORT_SYMBOL(LZ4_compress_destSize); 766 766 767 /*-****************************** 767 /*-****************************** 768 * Streaming functions 768 * Streaming functions 769 ********************************/ 769 ********************************/ 770 void LZ4_resetStream(LZ4_stream_t *LZ4_stream) 770 void LZ4_resetStream(LZ4_stream_t *LZ4_stream) 771 { 771 { 772 memset(LZ4_stream, 0, sizeof(LZ4_strea 772 memset(LZ4_stream, 0, sizeof(LZ4_stream_t)); 773 } 773 } 774 774 775 int LZ4_loadDict(LZ4_stream_t *LZ4_dict, 775 int LZ4_loadDict(LZ4_stream_t *LZ4_dict, 776 const char *dictionary, int dictSize) 776 const char *dictionary, int dictSize) 777 { 777 { 778 LZ4_stream_t_internal *dict = &LZ4_dic 778 LZ4_stream_t_internal *dict = &LZ4_dict->internal_donotuse; 779 const BYTE *p = (const BYTE *)dictiona 779 const BYTE *p = (const BYTE *)dictionary; 780 const BYTE * const dictEnd = p + dictS 780 const BYTE * const dictEnd = p + dictSize; 781 const BYTE *base; 781 const BYTE *base; 782 782 783 if ((dict->initCheck) 783 if ((dict->initCheck) 784 || (dict->currentOffset > 1 * 784 || (dict->currentOffset > 1 * GB)) { 785 /* Uninitialized structure, or 785 /* Uninitialized structure, or reuse overflow */ 786 LZ4_resetStream(LZ4_dict); 786 LZ4_resetStream(LZ4_dict); 787 } 787 } 788 788 789 if (dictSize < (int)HASH_UNIT) { 789 if (dictSize < (int)HASH_UNIT) { 790 dict->dictionary = NULL; 790 dict->dictionary = NULL; 791 dict->dictSize = 0; 791 dict->dictSize = 0; 792 return 0; 792 return 0; 793 } 793 } 794 794 795 if ((dictEnd - p) > 64 * KB) 795 if ((dictEnd - p) > 64 * KB) 796 p = dictEnd - 64 * KB; 796 p = dictEnd - 64 * KB; 797 dict->currentOffset += 64 * KB; 797 dict->currentOffset += 64 * KB; 798 base = p - dict->currentOffset; 798 base = p - dict->currentOffset; 799 dict->dictionary = p; 799 dict->dictionary = p; 800 dict->dictSize = (U32)(dictEnd - p); 800 dict->dictSize = (U32)(dictEnd - p); 801 dict->currentOffset += dict->dictSize; 801 dict->currentOffset += dict->dictSize; 802 802 803 while (p <= dictEnd - HASH_UNIT) { 803 while (p <= dictEnd - HASH_UNIT) { 804 LZ4_putPosition(p, dict->hashT 804 LZ4_putPosition(p, dict->hashTable, byU32, base); 805 p += 3; 805 p += 3; 806 } 806 } 807 807 808 return dict->dictSize; 808 return dict->dictSize; 809 } 809 } 810 EXPORT_SYMBOL(LZ4_loadDict); 810 EXPORT_SYMBOL(LZ4_loadDict); 811 811 812 static void LZ4_renormDictT(LZ4_stream_t_inter 812 static void LZ4_renormDictT(LZ4_stream_t_internal *LZ4_dict, 813 const BYTE *src) 813 const BYTE *src) 814 { 814 { 815 if ((LZ4_dict->currentOffset > 0x80000 815 if ((LZ4_dict->currentOffset > 0x80000000) || 816 ((uptrval)LZ4_dict->currentOff 816 ((uptrval)LZ4_dict->currentOffset > (uptrval)src)) { 817 /* address space overflow */ 817 /* address space overflow */ 818 /* rescale hash table */ 818 /* rescale hash table */ 819 U32 const delta = LZ4_dict->cu 819 U32 const delta = LZ4_dict->currentOffset - 64 * KB; 820 const BYTE *dictEnd = LZ4_dict 820 const BYTE *dictEnd = LZ4_dict->dictionary + LZ4_dict->dictSize; 821 int i; 821 int i; 822 822 823 for (i = 0; i < LZ4_HASH_SIZE_ 823 for (i = 0; i < LZ4_HASH_SIZE_U32; i++) { 824 if (LZ4_dict->hashTabl 824 if (LZ4_dict->hashTable[i] < delta) 825 LZ4_dict->hash 825 LZ4_dict->hashTable[i] = 0; 826 else 826 else 827 LZ4_dict->hash 827 LZ4_dict->hashTable[i] -= delta; 828 } 828 } 829 LZ4_dict->currentOffset = 64 * 829 LZ4_dict->currentOffset = 64 * KB; 830 if (LZ4_dict->dictSize > 64 * 830 if (LZ4_dict->dictSize > 64 * KB) 831 LZ4_dict->dictSize = 6 831 LZ4_dict->dictSize = 64 * KB; 832 LZ4_dict->dictionary = dictEnd 832 LZ4_dict->dictionary = dictEnd - LZ4_dict->dictSize; 833 } 833 } 834 } 834 } 835 835 836 int LZ4_saveDict(LZ4_stream_t *LZ4_dict, char 836 int LZ4_saveDict(LZ4_stream_t *LZ4_dict, char *safeBuffer, int dictSize) 837 { 837 { 838 LZ4_stream_t_internal * const dict = & 838 LZ4_stream_t_internal * const dict = &LZ4_dict->internal_donotuse; 839 const BYTE * const previousDictEnd = d 839 const BYTE * const previousDictEnd = dict->dictionary + dict->dictSize; 840 840 841 if ((U32)dictSize > 64 * KB) { 841 if ((U32)dictSize > 64 * KB) { 842 /* useless to define a diction 842 /* useless to define a dictionary > 64 * KB */ 843 dictSize = 64 * KB; 843 dictSize = 64 * KB; 844 } 844 } 845 if ((U32)dictSize > dict->dictSize) 845 if ((U32)dictSize > dict->dictSize) 846 dictSize = dict->dictSize; 846 dictSize = dict->dictSize; 847 847 848 memmove(safeBuffer, previousDictEnd - 848 memmove(safeBuffer, previousDictEnd - dictSize, dictSize); 849 849 850 dict->dictionary = (const BYTE *)safeB 850 dict->dictionary = (const BYTE *)safeBuffer; 851 dict->dictSize = (U32)dictSize; 851 dict->dictSize = (U32)dictSize; 852 852 853 return dictSize; 853 return dictSize; 854 } 854 } 855 EXPORT_SYMBOL(LZ4_saveDict); 855 EXPORT_SYMBOL(LZ4_saveDict); 856 856 857 int LZ4_compress_fast_continue(LZ4_stream_t *L 857 int LZ4_compress_fast_continue(LZ4_stream_t *LZ4_stream, const char *source, 858 char *dest, int inputSize, int maxOutp 858 char *dest, int inputSize, int maxOutputSize, int acceleration) 859 { 859 { 860 LZ4_stream_t_internal *streamPtr = &LZ 860 LZ4_stream_t_internal *streamPtr = &LZ4_stream->internal_donotuse; 861 const BYTE * const dictEnd = streamPtr 861 const BYTE * const dictEnd = streamPtr->dictionary 862 + streamPtr->dictSize; 862 + streamPtr->dictSize; 863 863 864 const BYTE *smallest = (const BYTE *) 864 const BYTE *smallest = (const BYTE *) source; 865 865 866 if (streamPtr->initCheck) { 866 if (streamPtr->initCheck) { 867 /* Uninitialized structure det 867 /* Uninitialized structure detected */ 868 return 0; 868 return 0; 869 } 869 } 870 870 871 if ((streamPtr->dictSize > 0) && (smal 871 if ((streamPtr->dictSize > 0) && (smallest > dictEnd)) 872 smallest = dictEnd; 872 smallest = dictEnd; 873 873 874 LZ4_renormDictT(streamPtr, smallest); 874 LZ4_renormDictT(streamPtr, smallest); 875 875 876 if (acceleration < 1) 876 if (acceleration < 1) 877 acceleration = LZ4_ACCELERATIO 877 acceleration = LZ4_ACCELERATION_DEFAULT; 878 878 879 /* Check overlapping input/dictionary 879 /* Check overlapping input/dictionary space */ 880 { 880 { 881 const BYTE *sourceEnd = (const 881 const BYTE *sourceEnd = (const BYTE *) source + inputSize; 882 882 883 if ((sourceEnd > streamPtr->di 883 if ((sourceEnd > streamPtr->dictionary) 884 && (sourceEnd < dictEn 884 && (sourceEnd < dictEnd)) { 885 streamPtr->dictSize = 885 streamPtr->dictSize = (U32)(dictEnd - sourceEnd); 886 if (streamPtr->dictSiz 886 if (streamPtr->dictSize > 64 * KB) 887 streamPtr->dic 887 streamPtr->dictSize = 64 * KB; 888 if (streamPtr->dictSiz 888 if (streamPtr->dictSize < 4) 889 streamPtr->dic 889 streamPtr->dictSize = 0; 890 streamPtr->dictionary 890 streamPtr->dictionary = dictEnd - streamPtr->dictSize; 891 } 891 } 892 } 892 } 893 893 894 /* prefix mode : source data follows d 894 /* prefix mode : source data follows dictionary */ 895 if (dictEnd == (const BYTE *)source) { 895 if (dictEnd == (const BYTE *)source) { 896 int result; 896 int result; 897 897 898 if ((streamPtr->dictSize < 64 898 if ((streamPtr->dictSize < 64 * KB) && 899 (streamPtr->dictSize < 899 (streamPtr->dictSize < streamPtr->currentOffset)) { 900 result = LZ4_compress_ 900 result = LZ4_compress_generic( 901 streamPtr, sou 901 streamPtr, source, dest, inputSize, 902 maxOutputSize, 902 maxOutputSize, limitedOutput, byU32, 903 withPrefix64k, 903 withPrefix64k, dictSmall, acceleration); 904 } else { 904 } else { 905 result = LZ4_compress_ 905 result = LZ4_compress_generic( 906 streamPtr, sou 906 streamPtr, source, dest, inputSize, 907 maxOutputSize, 907 maxOutputSize, limitedOutput, byU32, 908 withPrefix64k, 908 withPrefix64k, noDictIssue, acceleration); 909 } 909 } 910 streamPtr->dictSize += (U32)in 910 streamPtr->dictSize += (U32)inputSize; 911 streamPtr->currentOffset += (U 911 streamPtr->currentOffset += (U32)inputSize; 912 return result; 912 return result; 913 } 913 } 914 914 915 /* external dictionary mode */ 915 /* external dictionary mode */ 916 { 916 { 917 int result; 917 int result; 918 918 919 if ((streamPtr->dictSize < 64 919 if ((streamPtr->dictSize < 64 * KB) && 920 (streamPtr->dictSize < 920 (streamPtr->dictSize < streamPtr->currentOffset)) { 921 result = LZ4_compress_ 921 result = LZ4_compress_generic( 922 streamPtr, sou 922 streamPtr, source, dest, inputSize, 923 maxOutputSize, 923 maxOutputSize, limitedOutput, byU32, 924 usingExtDict, 924 usingExtDict, dictSmall, acceleration); 925 } else { 925 } else { 926 result = LZ4_compress_ 926 result = LZ4_compress_generic( 927 streamPtr, sou 927 streamPtr, source, dest, inputSize, 928 maxOutputSize, 928 maxOutputSize, limitedOutput, byU32, 929 usingExtDict, 929 usingExtDict, noDictIssue, acceleration); 930 } 930 } 931 streamPtr->dictionary = (const 931 streamPtr->dictionary = (const BYTE *)source; 932 streamPtr->dictSize = (U32)inp 932 streamPtr->dictSize = (U32)inputSize; 933 streamPtr->currentOffset += (U 933 streamPtr->currentOffset += (U32)inputSize; 934 return result; 934 return result; 935 } 935 } 936 } 936 } 937 EXPORT_SYMBOL(LZ4_compress_fast_continue); 937 EXPORT_SYMBOL(LZ4_compress_fast_continue); 938 938 939 MODULE_LICENSE("Dual BSD/GPL"); 939 MODULE_LICENSE("Dual BSD/GPL"); 940 MODULE_DESCRIPTION("LZ4 compressor"); 940 MODULE_DESCRIPTION("LZ4 compressor"); 941 941
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.