in plot-api/src/commonMain/kotlin/org/jetbrains/letsPlot/util/pngj/pixels/DeflaterEstimatorLz4.kt [95:174]
fun compress64k(src: ByteArray, srcOff: Int, srcLen: Int): Int {
val srcEnd = srcOff + srcLen
val srcLimit = srcEnd - LAST_LITERALS
val mflimit = srcEnd - MF_LIMIT
var sOff = srcOff
var dOff = 0
var anchor = sOff
if (srcLen >= MIN_LENGTH) {
val hashTable = ShortArray(HASH_TABLE_SIZE_64K)
++sOff
main@ while (true) {
// find a match
var forwardOff = sOff
var ref: Int
var findMatchAttempts = (1 shl SKIP_STRENGTH) + 3
do {
sOff = forwardOff
forwardOff += findMatchAttempts++ ushr SKIP_STRENGTH
if (forwardOff > mflimit) {
break@main
}
val h = hash64k(readInt(src, sOff))
ref = srcOff + readShort(hashTable, h)
writeShort(hashTable, h, sOff - srcOff)
} while (!readIntEquals(src, ref, sOff))
// catch up
val excess = commonBytesBackward(src, ref, sOff, srcOff, anchor)
sOff -= excess
ref -= excess
// sequence == refsequence
val runLen = sOff - anchor
dOff++
if (runLen >= RUN_MASK) {
if (runLen > RUN_MASK) dOff += (runLen - RUN_MASK) / 0xFF
dOff++
}
dOff += runLen
while (true) {
// encode offset
dOff += 2
// count nb matches
sOff += MIN_MATCH
ref += MIN_MATCH
val matchLen = commonBytes(src, ref, sOff, srcLimit)
sOff += matchLen
// encode match len
if (matchLen >= ML_MASK) {
if (matchLen >= ML_MASK + 0xFF) dOff += (matchLen - ML_MASK) / 0xFF
dOff++
}
// test end of chunk
if (sOff > mflimit) {
anchor = sOff
break@main
}
// fill table
writeShort(hashTable, hash64k(readInt(src, sOff - 2)), sOff - 2 - srcOff)
// test next position
val h = hash64k(readInt(src, sOff))
ref = srcOff + readShort(hashTable, h)
writeShort(hashTable, h, sOff - srcOff)
if (!readIntEquals(src, sOff, ref)) {
break
}
dOff++
}
// prepare next loop
anchor = sOff++
}
}
val runLen = srcEnd - anchor
if (runLen >= RUN_MASK + 0xFF) {
dOff += (runLen - RUN_MASK) / 0xFF
}
dOff++
dOff += runLen
return dOff
}