+static void unpack_alpha(GetBitContext *gb, uint16_t *dst, int num_coeffs,
+ const int num_bits)
+{
+ const int mask = (1 << num_bits) - 1;
+ int i, idx, val, alpha_val;
+
+ idx = 0;
+ alpha_val = mask;
+ do {
+ do {
+ if (get_bits1(gb))
+ val = get_bits(gb, num_bits);
+ else {
+ int sign;
+ val = get_bits(gb, num_bits == 16 ? 7 : 4);
+ sign = val & 1;
+ val = (val + 2) >> 1;
+ if (sign)
+ val = -val;
+ }
+ alpha_val = (alpha_val + val) & mask;
+ if (num_bits == 16)
+ dst[idx++] = alpha_val >> 6;
+ else
+ dst[idx++] = (alpha_val << 2) | (alpha_val >> 6);
+ if (idx >= num_coeffs - 1)
+ break;
+ } while (get_bits1(gb));
+ val = get_bits(gb, 4);
+ if (!val)
+ val = get_bits(gb, 11);
+ if (idx + val > num_coeffs)
+ val = num_coeffs - idx;
+ if (num_bits == 16)
+ for (i = 0; i < val; i++)
+ dst[idx++] = alpha_val >> 6;
+ else
+ for (i = 0; i < val; i++)
+ dst[idx++] = (alpha_val << 2) | (alpha_val >> 6);
+ } while (idx < num_coeffs);
+}
+
+/**
+ * Decode alpha slice plane.
+ */
+static void decode_alpha_plane(ProresContext *ctx, ProresThreadData *td,
+ const uint8_t *buf, int data_size,
+ uint16_t *out_ptr, int linesize,
+ int mbs_per_slice)
+{
+ GetBitContext gb;
+ int i;
+ uint16_t *block_ptr;
+
+ memset(td->blocks, 0, 8 * 4 * 64 * sizeof(*td->blocks));
+
+ init_get_bits(&gb, buf, data_size << 3);
+
+ if (ctx->alpha_info == 2)
+ unpack_alpha(&gb, td->blocks, mbs_per_slice * 4 * 64, 16);
+ else
+ unpack_alpha(&gb, td->blocks, mbs_per_slice * 4 * 64, 8);
+
+ block_ptr = td->blocks;
+
+ for (i = 0; i < 16; i++) {
+ memcpy(out_ptr, block_ptr, 16 * mbs_per_slice * sizeof(*out_ptr));
+ out_ptr += linesize >> 1;
+ block_ptr += 16 * mbs_per_slice;
+ }
+}
+