+static void put_alpha_diff(PutBitContext *pb, int cur, int prev, int abits)
+{
+ const int mask = (1 << abits) - 1;
+ const int dbits = (abits == 8) ? 4 : 7;
+ const int dsize = 1 << dbits - 1;
+ int diff = cur - prev;
+
+ diff &= mask;
+ if (diff >= (1 << abits) - dsize)
+ diff -= 1 << abits;
+ if (diff < -dsize || diff > dsize || !diff) {
+ put_bits(pb, 1, 1);
+ put_bits(pb, abits, diff);
+ } else {
+ put_bits(pb, 1, 0);
+ put_bits(pb, dbits - 1, FFABS(diff) - 1);
+ put_bits(pb, 1, diff < 0);
+ }
+}
+
+static void put_alpha_run(PutBitContext *pb, int run)
+{
+ if (run) {
+ put_bits(pb, 1, 0);
+ if (run < 0x10)
+ put_bits(pb, 4, run);
+ else
+ put_bits(pb, 15, run);
+ } else {
+ put_bits(pb, 1, 1);
+ }
+}
+
+// todo alpha quantisation for high quants
+static int encode_alpha_plane(ProresContext *ctx, PutBitContext *pb,
+ int mbs_per_slice, uint16_t *blocks,
+ int quant)
+{
+ const int abits = ctx->alpha_bits;
+ const int mask = (1 << abits) - 1;
+ const int num_coeffs = mbs_per_slice * 256;
+ int saved_pos = put_bits_count(pb);
+ int prev = mask, cur;
+ int idx = 0;
+ int run = 0;
+
+ cur = blocks[idx++];
+ put_alpha_diff(pb, cur, prev, abits);
+ prev = cur;
+ do {
+ cur = blocks[idx++];
+ if (cur != prev) {
+ put_alpha_run (pb, run);
+ put_alpha_diff(pb, cur, prev, abits);
+ prev = cur;
+ run = 0;
+ } else {
+ run++;
+ }
+ } while (idx < num_coeffs);
+ if (run)
+ put_alpha_run(pb, run);
+ flush_put_bits(pb);
+ return (put_bits_count(pb) - saved_pos) >> 3;
+}
+