0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036 #include <linux/lz4.h>
0037 #include "lz4defs.h"
0038 #include <linux/module.h>
0039 #include <linux/kernel.h>
0040 #include <asm/unaligned.h>
0041
0042 static const int LZ4_minLength = (MFLIMIT + 1);
0043 static const int LZ4_64Klimit = ((64 * KB) + (MFLIMIT - 1));
0044
0045
0046
0047
0048 static FORCE_INLINE U32 LZ4_hash4(
0049 U32 sequence,
0050 tableType_t const tableType)
0051 {
0052 if (tableType == byU16)
0053 return ((sequence * 2654435761U)
0054 >> ((MINMATCH * 8) - (LZ4_HASHLOG + 1)));
0055 else
0056 return ((sequence * 2654435761U)
0057 >> ((MINMATCH * 8) - LZ4_HASHLOG));
0058 }
0059
0060 static FORCE_INLINE U32 LZ4_hash5(
0061 U64 sequence,
0062 tableType_t const tableType)
0063 {
0064 const U32 hashLog = (tableType == byU16)
0065 ? LZ4_HASHLOG + 1
0066 : LZ4_HASHLOG;
0067
0068 #if LZ4_LITTLE_ENDIAN
0069 static const U64 prime5bytes = 889523592379ULL;
0070
0071 return (U32)(((sequence << 24) * prime5bytes) >> (64 - hashLog));
0072 #else
0073 static const U64 prime8bytes = 11400714785074694791ULL;
0074
0075 return (U32)(((sequence >> 24) * prime8bytes) >> (64 - hashLog));
0076 #endif
0077 }
0078
0079 static FORCE_INLINE U32 LZ4_hashPosition(
0080 const void *p,
0081 tableType_t const tableType)
0082 {
0083 #if LZ4_ARCH64
0084 if (tableType == byU32)
0085 return LZ4_hash5(LZ4_read_ARCH(p), tableType);
0086 #endif
0087
0088 return LZ4_hash4(LZ4_read32(p), tableType);
0089 }
0090
0091 static void LZ4_putPositionOnHash(
0092 const BYTE *p,
0093 U32 h,
0094 void *tableBase,
0095 tableType_t const tableType,
0096 const BYTE *srcBase)
0097 {
0098 switch (tableType) {
0099 case byPtr:
0100 {
0101 const BYTE **hashTable = (const BYTE **)tableBase;
0102
0103 hashTable[h] = p;
0104 return;
0105 }
0106 case byU32:
0107 {
0108 U32 *hashTable = (U32 *) tableBase;
0109
0110 hashTable[h] = (U32)(p - srcBase);
0111 return;
0112 }
0113 case byU16:
0114 {
0115 U16 *hashTable = (U16 *) tableBase;
0116
0117 hashTable[h] = (U16)(p - srcBase);
0118 return;
0119 }
0120 }
0121 }
0122
0123 static FORCE_INLINE void LZ4_putPosition(
0124 const BYTE *p,
0125 void *tableBase,
0126 tableType_t tableType,
0127 const BYTE *srcBase)
0128 {
0129 U32 const h = LZ4_hashPosition(p, tableType);
0130
0131 LZ4_putPositionOnHash(p, h, tableBase, tableType, srcBase);
0132 }
0133
0134 static const BYTE *LZ4_getPositionOnHash(
0135 U32 h,
0136 void *tableBase,
0137 tableType_t tableType,
0138 const BYTE *srcBase)
0139 {
0140 if (tableType == byPtr) {
0141 const BYTE **hashTable = (const BYTE **) tableBase;
0142
0143 return hashTable[h];
0144 }
0145
0146 if (tableType == byU32) {
0147 const U32 * const hashTable = (U32 *) tableBase;
0148
0149 return hashTable[h] + srcBase;
0150 }
0151
0152 {
0153
0154 const U16 * const hashTable = (U16 *) tableBase;
0155
0156 return hashTable[h] + srcBase;
0157 }
0158 }
0159
0160 static FORCE_INLINE const BYTE *LZ4_getPosition(
0161 const BYTE *p,
0162 void *tableBase,
0163 tableType_t tableType,
0164 const BYTE *srcBase)
0165 {
0166 U32 const h = LZ4_hashPosition(p, tableType);
0167
0168 return LZ4_getPositionOnHash(h, tableBase, tableType, srcBase);
0169 }
0170
0171
0172
0173
0174
0175
0176 static FORCE_INLINE int LZ4_compress_generic(
0177 LZ4_stream_t_internal * const dictPtr,
0178 const char * const source,
0179 char * const dest,
0180 const int inputSize,
0181 const int maxOutputSize,
0182 const limitedOutput_directive outputLimited,
0183 const tableType_t tableType,
0184 const dict_directive dict,
0185 const dictIssue_directive dictIssue,
0186 const U32 acceleration)
0187 {
0188 const BYTE *ip = (const BYTE *) source;
0189 const BYTE *base;
0190 const BYTE *lowLimit;
0191 const BYTE * const lowRefLimit = ip - dictPtr->dictSize;
0192 const BYTE * const dictionary = dictPtr->dictionary;
0193 const BYTE * const dictEnd = dictionary + dictPtr->dictSize;
0194 const size_t dictDelta = dictEnd - (const BYTE *)source;
0195 const BYTE *anchor = (const BYTE *) source;
0196 const BYTE * const iend = ip + inputSize;
0197 const BYTE * const mflimit = iend - MFLIMIT;
0198 const BYTE * const matchlimit = iend - LASTLITERALS;
0199
0200 BYTE *op = (BYTE *) dest;
0201 BYTE * const olimit = op + maxOutputSize;
0202
0203 U32 forwardH;
0204 size_t refDelta = 0;
0205
0206
0207 if ((U32)inputSize > (U32)LZ4_MAX_INPUT_SIZE) {
0208
0209 return 0;
0210 }
0211
0212 switch (dict) {
0213 case noDict:
0214 default:
0215 base = (const BYTE *)source;
0216 lowLimit = (const BYTE *)source;
0217 break;
0218 case withPrefix64k:
0219 base = (const BYTE *)source - dictPtr->currentOffset;
0220 lowLimit = (const BYTE *)source - dictPtr->dictSize;
0221 break;
0222 case usingExtDict:
0223 base = (const BYTE *)source - dictPtr->currentOffset;
0224 lowLimit = (const BYTE *)source;
0225 break;
0226 }
0227
0228 if ((tableType == byU16)
0229 && (inputSize >= LZ4_64Klimit)) {
0230
0231 return 0;
0232 }
0233
0234 if (inputSize < LZ4_minLength) {
0235
0236 goto _last_literals;
0237 }
0238
0239
0240 LZ4_putPosition(ip, dictPtr->hashTable, tableType, base);
0241 ip++;
0242 forwardH = LZ4_hashPosition(ip, tableType);
0243
0244
0245 for ( ; ; ) {
0246 const BYTE *match;
0247 BYTE *token;
0248
0249
0250 {
0251 const BYTE *forwardIp = ip;
0252 unsigned int step = 1;
0253 unsigned int searchMatchNb = acceleration << LZ4_SKIPTRIGGER;
0254
0255 do {
0256 U32 const h = forwardH;
0257
0258 ip = forwardIp;
0259 forwardIp += step;
0260 step = (searchMatchNb++ >> LZ4_SKIPTRIGGER);
0261
0262 if (unlikely(forwardIp > mflimit))
0263 goto _last_literals;
0264
0265 match = LZ4_getPositionOnHash(h,
0266 dictPtr->hashTable,
0267 tableType, base);
0268
0269 if (dict == usingExtDict) {
0270 if (match < (const BYTE *)source) {
0271 refDelta = dictDelta;
0272 lowLimit = dictionary;
0273 } else {
0274 refDelta = 0;
0275 lowLimit = (const BYTE *)source;
0276 } }
0277
0278 forwardH = LZ4_hashPosition(forwardIp,
0279 tableType);
0280
0281 LZ4_putPositionOnHash(ip, h, dictPtr->hashTable,
0282 tableType, base);
0283 } while (((dictIssue == dictSmall)
0284 ? (match < lowRefLimit)
0285 : 0)
0286 || ((tableType == byU16)
0287 ? 0
0288 : (match + MAX_DISTANCE < ip))
0289 || (LZ4_read32(match + refDelta)
0290 != LZ4_read32(ip)));
0291 }
0292
0293
0294 while (((ip > anchor) & (match + refDelta > lowLimit))
0295 && (unlikely(ip[-1] == match[refDelta - 1]))) {
0296 ip--;
0297 match--;
0298 }
0299
0300
0301 {
0302 unsigned const int litLength = (unsigned int)(ip - anchor);
0303
0304 token = op++;
0305
0306 if ((outputLimited) &&
0307
0308 (unlikely(op + litLength +
0309 (2 + 1 + LASTLITERALS) +
0310 (litLength / 255) > olimit)))
0311 return 0;
0312
0313 if (litLength >= RUN_MASK) {
0314 int len = (int)litLength - RUN_MASK;
0315
0316 *token = (RUN_MASK << ML_BITS);
0317
0318 for (; len >= 255; len -= 255)
0319 *op++ = 255;
0320 *op++ = (BYTE)len;
0321 } else
0322 *token = (BYTE)(litLength << ML_BITS);
0323
0324
0325 LZ4_wildCopy(op, anchor, op + litLength);
0326 op += litLength;
0327 }
0328
0329 _next_match:
0330
0331 LZ4_writeLE16(op, (U16)(ip - match));
0332 op += 2;
0333
0334
0335 {
0336 unsigned int matchCode;
0337
0338 if ((dict == usingExtDict)
0339 && (lowLimit == dictionary)) {
0340 const BYTE *limit;
0341
0342 match += refDelta;
0343 limit = ip + (dictEnd - match);
0344
0345 if (limit > matchlimit)
0346 limit = matchlimit;
0347
0348 matchCode = LZ4_count(ip + MINMATCH,
0349 match + MINMATCH, limit);
0350
0351 ip += MINMATCH + matchCode;
0352
0353 if (ip == limit) {
0354 unsigned const int more = LZ4_count(ip,
0355 (const BYTE *)source,
0356 matchlimit);
0357
0358 matchCode += more;
0359 ip += more;
0360 }
0361 } else {
0362 matchCode = LZ4_count(ip + MINMATCH,
0363 match + MINMATCH, matchlimit);
0364 ip += MINMATCH + matchCode;
0365 }
0366
0367 if (outputLimited &&
0368
0369 (unlikely(op +
0370 (1 + LASTLITERALS) +
0371 (matchCode >> 8) > olimit)))
0372 return 0;
0373
0374 if (matchCode >= ML_MASK) {
0375 *token += ML_MASK;
0376 matchCode -= ML_MASK;
0377 LZ4_write32(op, 0xFFFFFFFF);
0378
0379 while (matchCode >= 4 * 255) {
0380 op += 4;
0381 LZ4_write32(op, 0xFFFFFFFF);
0382 matchCode -= 4 * 255;
0383 }
0384
0385 op += matchCode / 255;
0386 *op++ = (BYTE)(matchCode % 255);
0387 } else
0388 *token += (BYTE)(matchCode);
0389 }
0390
0391 anchor = ip;
0392
0393
0394 if (ip > mflimit)
0395 break;
0396
0397
0398 LZ4_putPosition(ip - 2, dictPtr->hashTable, tableType, base);
0399
0400
0401 match = LZ4_getPosition(ip, dictPtr->hashTable,
0402 tableType, base);
0403
0404 if (dict == usingExtDict) {
0405 if (match < (const BYTE *)source) {
0406 refDelta = dictDelta;
0407 lowLimit = dictionary;
0408 } else {
0409 refDelta = 0;
0410 lowLimit = (const BYTE *)source;
0411 }
0412 }
0413
0414 LZ4_putPosition(ip, dictPtr->hashTable, tableType, base);
0415
0416 if (((dictIssue == dictSmall) ? (match >= lowRefLimit) : 1)
0417 && (match + MAX_DISTANCE >= ip)
0418 && (LZ4_read32(match + refDelta) == LZ4_read32(ip))) {
0419 token = op++;
0420 *token = 0;
0421 goto _next_match;
0422 }
0423
0424
0425 forwardH = LZ4_hashPosition(++ip, tableType);
0426 }
0427
0428 _last_literals:
0429
0430 {
0431 size_t const lastRun = (size_t)(iend - anchor);
0432
0433 if ((outputLimited) &&
0434
0435 ((op - (BYTE *)dest) + lastRun + 1 +
0436 ((lastRun + 255 - RUN_MASK) / 255) > (U32)maxOutputSize))
0437 return 0;
0438
0439 if (lastRun >= RUN_MASK) {
0440 size_t accumulator = lastRun - RUN_MASK;
0441 *op++ = RUN_MASK << ML_BITS;
0442 for (; accumulator >= 255; accumulator -= 255)
0443 *op++ = 255;
0444 *op++ = (BYTE) accumulator;
0445 } else {
0446 *op++ = (BYTE)(lastRun << ML_BITS);
0447 }
0448
0449 LZ4_memcpy(op, anchor, lastRun);
0450
0451 op += lastRun;
0452 }
0453
0454
0455 return (int) (((char *)op) - dest);
0456 }
0457
0458 static int LZ4_compress_fast_extState(
0459 void *state,
0460 const char *source,
0461 char *dest,
0462 int inputSize,
0463 int maxOutputSize,
0464 int acceleration)
0465 {
0466 LZ4_stream_t_internal *ctx = &((LZ4_stream_t *)state)->internal_donotuse;
0467 #if LZ4_ARCH64
0468 const tableType_t tableType = byU32;
0469 #else
0470 const tableType_t tableType = byPtr;
0471 #endif
0472
0473 LZ4_resetStream((LZ4_stream_t *)state);
0474
0475 if (acceleration < 1)
0476 acceleration = LZ4_ACCELERATION_DEFAULT;
0477
0478 if (maxOutputSize >= LZ4_COMPRESSBOUND(inputSize)) {
0479 if (inputSize < LZ4_64Klimit)
0480 return LZ4_compress_generic(ctx, source,
0481 dest, inputSize, 0,
0482 noLimit, byU16, noDict,
0483 noDictIssue, acceleration);
0484 else
0485 return LZ4_compress_generic(ctx, source,
0486 dest, inputSize, 0,
0487 noLimit, tableType, noDict,
0488 noDictIssue, acceleration);
0489 } else {
0490 if (inputSize < LZ4_64Klimit)
0491 return LZ4_compress_generic(ctx, source,
0492 dest, inputSize,
0493 maxOutputSize, limitedOutput, byU16, noDict,
0494 noDictIssue, acceleration);
0495 else
0496 return LZ4_compress_generic(ctx, source,
0497 dest, inputSize,
0498 maxOutputSize, limitedOutput, tableType, noDict,
0499 noDictIssue, acceleration);
0500 }
0501 }
0502
0503 int LZ4_compress_fast(const char *source, char *dest, int inputSize,
0504 int maxOutputSize, int acceleration, void *wrkmem)
0505 {
0506 return LZ4_compress_fast_extState(wrkmem, source, dest, inputSize,
0507 maxOutputSize, acceleration);
0508 }
0509 EXPORT_SYMBOL(LZ4_compress_fast);
0510
0511 int LZ4_compress_default(const char *source, char *dest, int inputSize,
0512 int maxOutputSize, void *wrkmem)
0513 {
0514 return LZ4_compress_fast(source, dest, inputSize,
0515 maxOutputSize, LZ4_ACCELERATION_DEFAULT, wrkmem);
0516 }
0517 EXPORT_SYMBOL(LZ4_compress_default);
0518
0519
0520
0521
0522 static int LZ4_compress_destSize_generic(
0523 LZ4_stream_t_internal * const ctx,
0524 const char * const src,
0525 char * const dst,
0526 int * const srcSizePtr,
0527 const int targetDstSize,
0528 const tableType_t tableType)
0529 {
0530 const BYTE *ip = (const BYTE *) src;
0531 const BYTE *base = (const BYTE *) src;
0532 const BYTE *lowLimit = (const BYTE *) src;
0533 const BYTE *anchor = ip;
0534 const BYTE * const iend = ip + *srcSizePtr;
0535 const BYTE * const mflimit = iend - MFLIMIT;
0536 const BYTE * const matchlimit = iend - LASTLITERALS;
0537
0538 BYTE *op = (BYTE *) dst;
0539 BYTE * const oend = op + targetDstSize;
0540 BYTE * const oMaxLit = op + targetDstSize - 2
0541 - 8 - 1 ;
0542 BYTE * const oMaxMatch = op + targetDstSize
0543 - (LASTLITERALS + 1 );
0544 BYTE * const oMaxSeq = oMaxLit - 1 ;
0545
0546 U32 forwardH;
0547
0548
0549
0550 if (targetDstSize < 1)
0551 return 0;
0552
0553 if ((U32)*srcSizePtr > (U32)LZ4_MAX_INPUT_SIZE)
0554 return 0;
0555
0556 if ((tableType == byU16) && (*srcSizePtr >= LZ4_64Klimit))
0557 return 0;
0558
0559 if (*srcSizePtr < LZ4_minLength)
0560 goto _last_literals;
0561
0562
0563 *srcSizePtr = 0;
0564 LZ4_putPosition(ip, ctx->hashTable, tableType, base);
0565 ip++; forwardH = LZ4_hashPosition(ip, tableType);
0566
0567
0568 for ( ; ; ) {
0569 const BYTE *match;
0570 BYTE *token;
0571
0572
0573 {
0574 const BYTE *forwardIp = ip;
0575 unsigned int step = 1;
0576 unsigned int searchMatchNb = 1 << LZ4_SKIPTRIGGER;
0577
0578 do {
0579 U32 h = forwardH;
0580
0581 ip = forwardIp;
0582 forwardIp += step;
0583 step = (searchMatchNb++ >> LZ4_SKIPTRIGGER);
0584
0585 if (unlikely(forwardIp > mflimit))
0586 goto _last_literals;
0587
0588 match = LZ4_getPositionOnHash(h, ctx->hashTable,
0589 tableType, base);
0590 forwardH = LZ4_hashPosition(forwardIp,
0591 tableType);
0592 LZ4_putPositionOnHash(ip, h,
0593 ctx->hashTable, tableType,
0594 base);
0595
0596 } while (((tableType == byU16)
0597 ? 0
0598 : (match + MAX_DISTANCE < ip))
0599 || (LZ4_read32(match) != LZ4_read32(ip)));
0600 }
0601
0602
0603 while ((ip > anchor)
0604 && (match > lowLimit)
0605 && (unlikely(ip[-1] == match[-1]))) {
0606 ip--;
0607 match--;
0608 }
0609
0610
0611 {
0612 unsigned int litLength = (unsigned int)(ip - anchor);
0613
0614 token = op++;
0615 if (op + ((litLength + 240) / 255)
0616 + litLength > oMaxLit) {
0617
0618 op--;
0619 goto _last_literals;
0620 }
0621 if (litLength >= RUN_MASK) {
0622 unsigned int len = litLength - RUN_MASK;
0623 *token = (RUN_MASK<<ML_BITS);
0624 for (; len >= 255; len -= 255)
0625 *op++ = 255;
0626 *op++ = (BYTE)len;
0627 } else
0628 *token = (BYTE)(litLength << ML_BITS);
0629
0630
0631 LZ4_wildCopy(op, anchor, op + litLength);
0632 op += litLength;
0633 }
0634
0635 _next_match:
0636
0637 LZ4_writeLE16(op, (U16)(ip - match)); op += 2;
0638
0639
0640 {
0641 size_t matchLength = LZ4_count(ip + MINMATCH,
0642 match + MINMATCH, matchlimit);
0643
0644 if (op + ((matchLength + 240)/255) > oMaxMatch) {
0645
0646 matchLength = (15 - 1) + (oMaxMatch - op) * 255;
0647 }
0648 ip += MINMATCH + matchLength;
0649
0650 if (matchLength >= ML_MASK) {
0651 *token += ML_MASK;
0652 matchLength -= ML_MASK;
0653 while (matchLength >= 255) {
0654 matchLength -= 255;
0655 *op++ = 255;
0656 }
0657 *op++ = (BYTE)matchLength;
0658 } else
0659 *token += (BYTE)(matchLength);
0660 }
0661
0662 anchor = ip;
0663
0664
0665 if (ip > mflimit)
0666 break;
0667 if (op > oMaxSeq)
0668 break;
0669
0670
0671 LZ4_putPosition(ip - 2, ctx->hashTable, tableType, base);
0672
0673
0674 match = LZ4_getPosition(ip, ctx->hashTable, tableType, base);
0675 LZ4_putPosition(ip, ctx->hashTable, tableType, base);
0676
0677 if ((match + MAX_DISTANCE >= ip)
0678 && (LZ4_read32(match) == LZ4_read32(ip))) {
0679 token = op++; *token = 0;
0680 goto _next_match;
0681 }
0682
0683
0684 forwardH = LZ4_hashPosition(++ip, tableType);
0685 }
0686
0687 _last_literals:
0688
0689 {
0690 size_t lastRunSize = (size_t)(iend - anchor);
0691
0692 if (op + 1
0693 + ((lastRunSize + 240) / 255)
0694 + lastRunSize > oend) {
0695
0696 lastRunSize = (oend - op) - 1;
0697 lastRunSize -= (lastRunSize + 240) / 255;
0698 }
0699 ip = anchor + lastRunSize;
0700
0701 if (lastRunSize >= RUN_MASK) {
0702 size_t accumulator = lastRunSize - RUN_MASK;
0703
0704 *op++ = RUN_MASK << ML_BITS;
0705 for (; accumulator >= 255; accumulator -= 255)
0706 *op++ = 255;
0707 *op++ = (BYTE) accumulator;
0708 } else {
0709 *op++ = (BYTE)(lastRunSize<<ML_BITS);
0710 }
0711 LZ4_memcpy(op, anchor, lastRunSize);
0712 op += lastRunSize;
0713 }
0714
0715
0716 *srcSizePtr = (int) (((const char *)ip) - src);
0717 return (int) (((char *)op) - dst);
0718 }
0719
0720 static int LZ4_compress_destSize_extState(
0721 LZ4_stream_t *state,
0722 const char *src,
0723 char *dst,
0724 int *srcSizePtr,
0725 int targetDstSize)
0726 {
0727 #if LZ4_ARCH64
0728 const tableType_t tableType = byU32;
0729 #else
0730 const tableType_t tableType = byPtr;
0731 #endif
0732
0733 LZ4_resetStream(state);
0734
0735 if (targetDstSize >= LZ4_COMPRESSBOUND(*srcSizePtr)) {
0736
0737 return LZ4_compress_fast_extState(
0738 state, src, dst, *srcSizePtr,
0739 targetDstSize, 1);
0740 } else {
0741 if (*srcSizePtr < LZ4_64Klimit)
0742 return LZ4_compress_destSize_generic(
0743 &state->internal_donotuse,
0744 src, dst, srcSizePtr,
0745 targetDstSize, byU16);
0746 else
0747 return LZ4_compress_destSize_generic(
0748 &state->internal_donotuse,
0749 src, dst, srcSizePtr,
0750 targetDstSize, tableType);
0751 }
0752 }
0753
0754
0755 int LZ4_compress_destSize(
0756 const char *src,
0757 char *dst,
0758 int *srcSizePtr,
0759 int targetDstSize,
0760 void *wrkmem)
0761 {
0762 return LZ4_compress_destSize_extState(wrkmem, src, dst, srcSizePtr,
0763 targetDstSize);
0764 }
0765 EXPORT_SYMBOL(LZ4_compress_destSize);
0766
0767
0768
0769
0770 void LZ4_resetStream(LZ4_stream_t *LZ4_stream)
0771 {
0772 memset(LZ4_stream, 0, sizeof(LZ4_stream_t));
0773 }
0774
0775 int LZ4_loadDict(LZ4_stream_t *LZ4_dict,
0776 const char *dictionary, int dictSize)
0777 {
0778 LZ4_stream_t_internal *dict = &LZ4_dict->internal_donotuse;
0779 const BYTE *p = (const BYTE *)dictionary;
0780 const BYTE * const dictEnd = p + dictSize;
0781 const BYTE *base;
0782
0783 if ((dict->initCheck)
0784 || (dict->currentOffset > 1 * GB)) {
0785
0786 LZ4_resetStream(LZ4_dict);
0787 }
0788
0789 if (dictSize < (int)HASH_UNIT) {
0790 dict->dictionary = NULL;
0791 dict->dictSize = 0;
0792 return 0;
0793 }
0794
0795 if ((dictEnd - p) > 64 * KB)
0796 p = dictEnd - 64 * KB;
0797 dict->currentOffset += 64 * KB;
0798 base = p - dict->currentOffset;
0799 dict->dictionary = p;
0800 dict->dictSize = (U32)(dictEnd - p);
0801 dict->currentOffset += dict->dictSize;
0802
0803 while (p <= dictEnd - HASH_UNIT) {
0804 LZ4_putPosition(p, dict->hashTable, byU32, base);
0805 p += 3;
0806 }
0807
0808 return dict->dictSize;
0809 }
0810 EXPORT_SYMBOL(LZ4_loadDict);
0811
0812 static void LZ4_renormDictT(LZ4_stream_t_internal *LZ4_dict,
0813 const BYTE *src)
0814 {
0815 if ((LZ4_dict->currentOffset > 0x80000000) ||
0816 ((uptrval)LZ4_dict->currentOffset > (uptrval)src)) {
0817
0818
0819 U32 const delta = LZ4_dict->currentOffset - 64 * KB;
0820 const BYTE *dictEnd = LZ4_dict->dictionary + LZ4_dict->dictSize;
0821 int i;
0822
0823 for (i = 0; i < LZ4_HASH_SIZE_U32; i++) {
0824 if (LZ4_dict->hashTable[i] < delta)
0825 LZ4_dict->hashTable[i] = 0;
0826 else
0827 LZ4_dict->hashTable[i] -= delta;
0828 }
0829 LZ4_dict->currentOffset = 64 * KB;
0830 if (LZ4_dict->dictSize > 64 * KB)
0831 LZ4_dict->dictSize = 64 * KB;
0832 LZ4_dict->dictionary = dictEnd - LZ4_dict->dictSize;
0833 }
0834 }
0835
0836 int LZ4_saveDict(LZ4_stream_t *LZ4_dict, char *safeBuffer, int dictSize)
0837 {
0838 LZ4_stream_t_internal * const dict = &LZ4_dict->internal_donotuse;
0839 const BYTE * const previousDictEnd = dict->dictionary + dict->dictSize;
0840
0841 if ((U32)dictSize > 64 * KB) {
0842
0843 dictSize = 64 * KB;
0844 }
0845 if ((U32)dictSize > dict->dictSize)
0846 dictSize = dict->dictSize;
0847
0848 memmove(safeBuffer, previousDictEnd - dictSize, dictSize);
0849
0850 dict->dictionary = (const BYTE *)safeBuffer;
0851 dict->dictSize = (U32)dictSize;
0852
0853 return dictSize;
0854 }
0855 EXPORT_SYMBOL(LZ4_saveDict);
0856
0857 int LZ4_compress_fast_continue(LZ4_stream_t *LZ4_stream, const char *source,
0858 char *dest, int inputSize, int maxOutputSize, int acceleration)
0859 {
0860 LZ4_stream_t_internal *streamPtr = &LZ4_stream->internal_donotuse;
0861 const BYTE * const dictEnd = streamPtr->dictionary
0862 + streamPtr->dictSize;
0863
0864 const BYTE *smallest = (const BYTE *) source;
0865
0866 if (streamPtr->initCheck) {
0867
0868 return 0;
0869 }
0870
0871 if ((streamPtr->dictSize > 0) && (smallest > dictEnd))
0872 smallest = dictEnd;
0873
0874 LZ4_renormDictT(streamPtr, smallest);
0875
0876 if (acceleration < 1)
0877 acceleration = LZ4_ACCELERATION_DEFAULT;
0878
0879
0880 {
0881 const BYTE *sourceEnd = (const BYTE *) source + inputSize;
0882
0883 if ((sourceEnd > streamPtr->dictionary)
0884 && (sourceEnd < dictEnd)) {
0885 streamPtr->dictSize = (U32)(dictEnd - sourceEnd);
0886 if (streamPtr->dictSize > 64 * KB)
0887 streamPtr->dictSize = 64 * KB;
0888 if (streamPtr->dictSize < 4)
0889 streamPtr->dictSize = 0;
0890 streamPtr->dictionary = dictEnd - streamPtr->dictSize;
0891 }
0892 }
0893
0894
0895 if (dictEnd == (const BYTE *)source) {
0896 int result;
0897
0898 if ((streamPtr->dictSize < 64 * KB) &&
0899 (streamPtr->dictSize < streamPtr->currentOffset)) {
0900 result = LZ4_compress_generic(
0901 streamPtr, source, dest, inputSize,
0902 maxOutputSize, limitedOutput, byU32,
0903 withPrefix64k, dictSmall, acceleration);
0904 } else {
0905 result = LZ4_compress_generic(
0906 streamPtr, source, dest, inputSize,
0907 maxOutputSize, limitedOutput, byU32,
0908 withPrefix64k, noDictIssue, acceleration);
0909 }
0910 streamPtr->dictSize += (U32)inputSize;
0911 streamPtr->currentOffset += (U32)inputSize;
0912 return result;
0913 }
0914
0915
0916 {
0917 int result;
0918
0919 if ((streamPtr->dictSize < 64 * KB) &&
0920 (streamPtr->dictSize < streamPtr->currentOffset)) {
0921 result = LZ4_compress_generic(
0922 streamPtr, source, dest, inputSize,
0923 maxOutputSize, limitedOutput, byU32,
0924 usingExtDict, dictSmall, acceleration);
0925 } else {
0926 result = LZ4_compress_generic(
0927 streamPtr, source, dest, inputSize,
0928 maxOutputSize, limitedOutput, byU32,
0929 usingExtDict, noDictIssue, acceleration);
0930 }
0931 streamPtr->dictionary = (const BYTE *)source;
0932 streamPtr->dictSize = (U32)inputSize;
0933 streamPtr->currentOffset += (U32)inputSize;
0934 return result;
0935 }
0936 }
0937 EXPORT_SYMBOL(LZ4_compress_fast_continue);
0938
0939 MODULE_LICENSE("Dual BSD/GPL");
0940 MODULE_DESCRIPTION("LZ4 compressor");