| 172 | } |
| 173 | |
| 174 | static int decode_slice_header(const FFV1Context *f, |
| 175 | FFV1SliceContext *sc, AVFrame *frame) |
| 176 | { |
| 177 | RangeCoder *c = &sc->c; |
| 178 | uint8_t state[CONTEXT_SIZE]; |
| 179 | unsigned ps, context_count; |
| 180 | int sx, sy, sw, sh; |
| 181 | |
| 182 | memset(state, 128, sizeof(state)); |
| 183 | sx = ff_ffv1_get_symbol(c, state, 0); |
| 184 | sy = ff_ffv1_get_symbol(c, state, 0); |
| 185 | sw = ff_ffv1_get_symbol(c, state, 0) + 1U; |
| 186 | sh = ff_ffv1_get_symbol(c, state, 0) + 1U; |
| 187 | |
| 188 | av_assert0(f->version > 2); |
| 189 | |
| 190 | |
| 191 | if (sx < 0 || sy < 0 || sw <= 0 || sh <= 0) |
| 192 | return AVERROR_INVALIDDATA; |
| 193 | if (sx > f->num_h_slices - sw || sy > f->num_v_slices - sh) |
| 194 | return AVERROR_INVALIDDATA; |
| 195 | |
| 196 | sc->slice_x = ff_slice_coord(f, f->width , sx , f->num_h_slices, f->chroma_h_shift); |
| 197 | sc->slice_y = ff_slice_coord(f, f->height, sy , f->num_v_slices, f->chroma_v_shift); |
| 198 | sc->slice_width = ff_slice_coord(f, f->width , sx + sw, f->num_h_slices, f->chroma_h_shift) - sc->slice_x; |
| 199 | sc->slice_height = ff_slice_coord(f, f->height, sy + sh, f->num_v_slices, f->chroma_v_shift) - sc->slice_y; |
| 200 | |
| 201 | av_assert0((unsigned)sc->slice_width <= f->width && |
| 202 | (unsigned)sc->slice_height <= f->height); |
| 203 | av_assert0 ( (unsigned)sc->slice_x + (uint64_t)sc->slice_width <= f->width |
| 204 | && (unsigned)sc->slice_y + (uint64_t)sc->slice_height <= f->height); |
| 205 | |
| 206 | if (f->ac == AC_GOLOMB_RICE && sc->slice_width >= (1<<23)) |
| 207 | return AVERROR_INVALIDDATA; |
| 208 | |
| 209 | for (unsigned i = 0; i < f->plane_count; i++) { |
| 210 | PlaneContext * const p = &sc->plane[i]; |
| 211 | int idx = ff_ffv1_get_symbol(c, state, 0); |
| 212 | if (idx >= (unsigned)f->quant_table_count) { |
| 213 | av_log(f->avctx, AV_LOG_ERROR, "quant_table_index out of range\n"); |
| 214 | return -1; |
| 215 | } |
| 216 | p->quant_table_index = idx; |
| 217 | context_count = f->context_count[idx]; |
| 218 | |
| 219 | if (p->context_count < context_count) { |
| 220 | av_freep(&p->state); |
| 221 | av_freep(&p->vlc_state); |
| 222 | } |
| 223 | p->context_count = context_count; |
| 224 | } |
| 225 | |
| 226 | ps = ff_ffv1_get_symbol(c, state, 0); |
| 227 | if (ps == 1) { |
| 228 | frame->flags |= AV_FRAME_FLAG_INTERLACED; |
| 229 | frame->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST; |
| 230 | } else if (ps == 2) { |
| 231 | frame->flags |= AV_FRAME_FLAG_INTERLACED; |
no test coverage detected