This improves compression by 0.1% overall and 44% for the changed table I tried several other things but so far this is the best compromise between complexity and compression This can also be extended to 32 and 64bit floats
Unified · Split
| @@ -159,12 +159,25 @@ static int RENAME(decode_rgb_frame)(FFV1Context *f, FFV1SliceContext *sc, · 158 unmodified lines | ||
| 159 | 159 | for (int p= 0; p<3 + transparency; p++) { |
| 160 | 160 | int j = 0; |
| 161 | 161 | int lu = 0; |
| 162 | − uint8_t state[2] = {128, 128}; | |
| 162 | + uint8_t state[2][32]; | |
| 163 | + memset(state, 128, sizeof(state)); | |
| 164 | + | |
| 163 | 165 | for (int i= 0; i<65536; i++) { |
| 164 | − int u = get_rac(&sc->c, state + lu); | |
| 165 | − sc->fltmap[p][j] = i ^ ((i&0x8000) ? 0 : 0x7FFF); | |
| 166 | − j+= u; | |
| 167 | − lu = u; | |
| 166 | + int run = get_symbol_inline(&sc->c, state[lu], 0); | |
| 167 | + if (run > 65536U - i) | |
| 168 | + return AVERROR_INVALIDDATA; | |
| 169 | + if (lu) { | |
| 170 | + lu ^= !run; | |
| 171 | + while (run--) { | |
| 172 | + sc->fltmap[p][j++] = i ^ ((i&0x8000) ? 0 : 0x7FFF); | |
| 173 | + i++; | |
| 174 | + } | |
| 175 | + } else { | |
| 176 | + i += run; | |
| 177 | + if (i != 65536) | |
| 178 | + sc->fltmap[p][j++] = i ^ ((i&0x8000) ? 0 : 0x7FFF); | |
| 179 | + lu ^= !run; | |
| 180 | + } | |
| 168 | 181 | } |
| 169 | 182 | } |
| 170 | 183 | } |
| @@ -177,15 +177,26 @@ static int RENAME(encode_rgb_frame)(FFV1Context *f, FFV1SliceContext *sc, · 176 unmodified lines | ||
| 177 | 177 | for (int p= 0; p<3 + transparency; p++) { |
| 178 | 178 | int j = 0; |
| 179 | 179 | int lu = 0; |
| 180 | − uint8_t state[2] = {128, 128}; | |
| 180 | + uint8_t state[2][32]; | |
| 181 | + int run = 0; | |
| 182 | + memset(state, 128, sizeof(state)); | |
| 181 | 183 | for (int i= 0; i<65536; i++) { |
| 182 | 184 | int ri = i ^ ((i&0x8000) ? 0 : 0x7FFF); |
| 183 | 185 | int u = sc->fltmap[p][ri]; |
| 184 | 186 | sc->fltmap[p][ri] = j; |
| 185 | 187 | j+= u; |
| 186 | − put_rac(&sc->c, state + lu, u); | |
| 187 | − lu = u; | |
| 188 | + | |
| 189 | + if (lu == u) { | |
| 190 | + run ++; | |
| 191 | + } else { | |
| 192 | + put_symbol_inline(&sc->c, state[lu], run, 0, NULL, NULL); | |
| 193 | + if (run == 0) | |
| 194 | + lu = u; | |
| 195 | + run = 0; | |
| 196 | + } | |
| 188 | 197 | } |
| 198 | + if (run) | |
| 199 | + put_symbol(&sc->c, state[lu], run, 0); | |
| 189 | 200 | } |
| 190 | 201 | } |
| 191 | 202 | |