| 850 | } |
| 851 | |
| 852 | static int binkb_decode_plane(BinkContext *c, AVFrame *frame, GetBitContext *gb, |
| 853 | int plane_idx, int is_key, int is_chroma) |
| 854 | { |
| 855 | int blk, ret; |
| 856 | int i, j, bx, by; |
| 857 | uint8_t *dst, *ref, *ref_start, *ref_end; |
| 858 | int v, col[2]; |
| 859 | const uint8_t *scan; |
| 860 | int xoff, yoff; |
| 861 | LOCAL_ALIGNED_32(int16_t, block, [64]); |
| 862 | LOCAL_ALIGNED_16(int32_t, dctblock, [64]); |
| 863 | int coordmap[64]; |
| 864 | int ybias = is_key ? -15 : 0; |
| 865 | int qp, quant_idx, coef_count, coef_idx[64]; |
| 866 | |
| 867 | const int stride = frame->linesize[plane_idx]; |
| 868 | int bw = is_chroma ? (c->avctx->width + 15) >> 4 : (c->avctx->width + 7) >> 3; |
| 869 | int bh = is_chroma ? (c->avctx->height + 15) >> 4 : (c->avctx->height + 7) >> 3; |
| 870 | |
| 871 | binkb_init_bundles(c); |
| 872 | ref_start = frame->data[plane_idx]; |
| 873 | ref_end = frame->data[plane_idx] + ((bh - 1) * frame->linesize[plane_idx] + bw - 1) * 8; |
| 874 | |
| 875 | for (i = 0; i < 64; i++) |
| 876 | coordmap[i] = (i & 7) + (i >> 3) * stride; |
| 877 | |
| 878 | for (by = 0; by < bh; by++) { |
| 879 | for (i = 0; i < BINKB_NB_SRC; i++) { |
| 880 | if ((ret = binkb_read_bundle(c, gb, i)) < 0) |
| 881 | return ret; |
| 882 | } |
| 883 | |
| 884 | dst = frame->data[plane_idx] + 8*by*stride; |
| 885 | for (bx = 0; bx < bw; bx++, dst += 8) { |
| 886 | blk = binkb_get_value(c, BINKB_SRC_BLOCK_TYPES); |
| 887 | switch (blk) { |
| 888 | case 0: |
| 889 | break; |
| 890 | case 1: |
| 891 | scan = bink_patterns[get_bits(gb, 4)]; |
| 892 | i = 0; |
| 893 | do { |
| 894 | int mode, run; |
| 895 | |
| 896 | mode = get_bits1(gb); |
| 897 | run = get_bits(gb, binkb_runbits[i]) + 1; |
| 898 | |
| 899 | i += run; |
| 900 | if (i > 64) { |
| 901 | av_log(c->avctx, AV_LOG_ERROR, "Run went out of bounds\n"); |
| 902 | return AVERROR_INVALIDDATA; |
| 903 | } |
| 904 | if (mode) { |
| 905 | v = binkb_get_value(c, BINKB_SRC_COLORS); |
| 906 | for (j = 0; j < run; j++) |
| 907 | dst[coordmap[*scan++]] = v; |
| 908 | } else { |
| 909 | for (j = 0; j < run; j++) |
no test coverage detected