MCPcopy Create free account
hub / github.com/OpenXcom/OpenXcom / encodeLZ77

Function encodeLZ77

src/lodepng.cpp:1431–1596  ·  view source on GitHub ↗

LZ77-encode the data. Return value is error code. The input are raw bytes, the output is in the form of unsigned integers with codes representing for example literal bytes, or length/distance pairs. It uses a hash table technique to let it encode faster. When doing LZ77 encoding, a sliding window (of windowsize) is used, and all past bytes in that window can be used as the "dictionary". A brute fo

Source from the content-addressed store, hash-verified

1429this hash technique is one out of several ways to speed this up.
1430*/
1431static unsigned encodeLZ77(uivector* out, Hash* hash,
1432 const unsigned char* in, size_t inpos, size_t insize, unsigned windowsize,
1433 unsigned minmatch, unsigned nicematch, unsigned lazymatching)
1434{
1435 unsigned pos, i, error = 0;
1436 /*for large window lengths, assume the user wants no compression loss. Otherwise, max hash chain length speedup.*/
1437 unsigned maxchainlength = windowsize >= 8192 ? windowsize : windowsize / 8;
1438 unsigned maxlazymatch = windowsize >= 8192 ? MAX_SUPPORTED_DEFLATE_LENGTH : 64;
1439
1440 unsigned usezeros = 1; /*not sure if setting it to false for windowsize < 8192 is better or worse*/
1441 unsigned numzeros = 0;
1442
1443 unsigned offset; /*the offset represents the distance in LZ77 terminology*/
1444 unsigned length;
1445 unsigned lazy = 0;
1446 unsigned lazylength = 0, lazyoffset = 0;
1447 unsigned hashval;
1448 unsigned current_offset, current_length;
1449 const unsigned char *lastptr, *foreptr, *backptr;
1450 unsigned hashpos, prevpos;
1451
1452 if(windowsize <= 0 || windowsize > 32768) return 60; /*error: windowsize smaller/larger than allowed*/
1453 if((windowsize & (windowsize - 1)) != 0) return 90; /*error: must be power of two*/
1454
1455 if(nicematch > MAX_SUPPORTED_DEFLATE_LENGTH) nicematch = MAX_SUPPORTED_DEFLATE_LENGTH;
1456
1457 for(pos = inpos; pos < insize; pos++)
1458 {
1459 size_t wpos = pos & (windowsize - 1); /*position for in 'circular' hash buffers*/
1460 unsigned chainlength = 0;
1461
1462 hashval = getHash(in, insize, pos);
1463 updateHashChain(hash, wpos, hashval);
1464
1465 if(usezeros && hashval == 0)
1466 {
1467 if (numzeros == 0) numzeros = countZeros(in, insize, pos);
1468 else if (pos + numzeros >= insize || in[pos + numzeros - 1] != 0) numzeros--;
1469 hash->zeros[wpos] = numzeros;
1470 }
1471 else
1472 {
1473 numzeros = 0;
1474 }
1475
1476 /*the length and offset found for the current position*/
1477 length = 0;
1478 offset = 0;
1479
1480 prevpos = hash->head[hashval];
1481 hashpos = hash->chain[prevpos];
1482
1483 lastptr = &in[insize < pos + MAX_SUPPORTED_DEFLATE_LENGTH ? insize : pos + MAX_SUPPORTED_DEFLATE_LENGTH];
1484
1485 /*search for the longest string*/
1486 for(;;)
1487 {
1488 /*stop when went completely around the circular buffer*/

Callers 2

deflateDynamicFunction · 0.85
deflateFixedFunction · 0.85

Calls 5

getHashFunction · 0.85
updateHashChainFunction · 0.85
countZerosFunction · 0.85
uivector_push_backFunction · 0.85
addLengthDistanceFunction · 0.85

Tested by

no test coverage detected