-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPpmEncoder.kt
46 lines (36 loc) · 1.49 KB
/
PpmEncoder.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import arithmeticEncoder.ArithmeticEncoder
import arithmeticEncoder.FlatFrequencyTable
import arithmeticEncoder.SimpleFrequencyTable
class PpmEncoder(
private val encoder: ArithmeticEncoder,
private val maxContextOrder: Int
) {
private val remainingSymbols: MutableList<Int> = (0..256).toMutableList()
private var context = Context(-1, -1, null)
fun encode(symbol: Int) {
context = encodeAux(context, symbol)
}
private fun encodeAux(context: Context, symbol: Int): Context {
if(context.order == maxContextOrder) { // cant create a context with higher order, go to shorter context
return encodeAux(context.vine!!, symbol)
}
val (frequencies, symbolContext, index) = context.getFrequenciesAndSymbolContext(symbol)
// encode if have children
if(frequencies.isNotEmpty()) encoder.write(SimpleFrequencyTable(frequencies), index)
return if(symbolContext == null) { // symbol not found in this context
val vine = if(context.isRoot) {
writeNewSymbol(symbol)
context
} else encodeAux(context.vine!!, symbol)
context.newChild(symbol, vine)
} else {
symbolContext.increment()
symbolContext
}
}
private fun writeNewSymbol(symbol: Int) {
val index = remainingSymbols.indexOf(symbol)
encoder.write(FlatFrequencyTable(remainingSymbols.size), index)
remainingSymbols.removeAt(index)
}
}