/* * Amuse Graphics Movie decoder * * Copyright (c) 2018 Paul B Mahol * * This file is part of FFmpeg. * * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include <string.h> #define BITSTREAM_READER_LE #include "libavutil/mem.h"#include "libavutil/mem_internal.h" #include "avcodec.h"#include "bytestream.h"#include "codec_internal.h"#include "copy_block.h"#include "decode.h"#include "get_bits.h"#include "idctdsp.h"#include "jpegquanttables.h" typedef struct MotionVector { int16_t x, y;} MotionVector; typedef struct AGMContext { const AVClass *class; AVCodecContext *avctx; GetBitContext gb; GetByteContext gbyte; int key_frame; int bitstream_size; int compression; int blocks_w; int blocks_h; int size[3]; int plus; int dct; int rgb; unsigned flags; unsigned fflags; uint8_t *output; unsigned padded_output_size; unsigned output_size; MotionVector *mvectors; unsigned mvectors_size; VLC vlc; AVFrame *prev_frame; int luma_quant_matrix[64]; int chroma_quant_matrix[64]; uint8_t permutated_scantable[64]; DECLARE_ALIGNED(32, int16_t, block)[64]; int16_t *wblocks; unsigned wblocks_size; int *map; unsigned map_size; IDCTDSPContext idsp;} AGMContext; static int read_code(GetBitContext *gb, int *oskip, int *level, int *map, int mode){ int len = 0, skip = 0, max; if (get_bits_left(gb) < 2) return AVERROR_INVALIDDATA; if (show_bits(gb, 2)) { switch (show_bits(gb, 4)) { case 1: case 9: len = 1; skip = 3; break; case 2: len = 3; skip = 4; break; case 3: len = 7; skip = 4; break; case 5: case 13: len = 2; skip = 3; break; case 6: len = 4; skip = 4; break; case 7: len = 8; skip = 4; break; case 10: len = 5; skip = 4; break; case 11: len = 9; skip = 4; break; case 14: len = 6; skip = 4; break; case 15: len = ((show_bits(gb, 5) & 0x10) | 0xA0) >> 4; skip = 5; break; default: return AVERROR_INVALIDDATA; } skip_bits(gb, skip); *level = get_bits(gb, len); *map = 1; *oskip = 0; max = 1 << (len - 1); if (*level < max) *level = -(max + *level); } else if (show_bits(gb, 3) & 4) { skip_bits(gb, 3); if (mode == 1) { if (show_bits(gb, 4)) { if (show_bits(gb, 4) == 1) { skip_bits(gb, 4); *oskip = get_bits(gb, 16); } else { *oskip = get_bits(gb, 4); } } else { skip_bits(gb, 4); *oskip = get_bits(gb, 10); } } else if (mode == 0) { *oskip = get_bits(gb, 10); } *level = 0; } else { skip_bits(gb, 3); if (mode == 0) *oskip = get_bits(gb, 4); else if (mode == 1) *oskip = 0; *level = 0; } return 0;} static int decode_intra_blocks(AGMContext *s, GetBitContext *gb, const int *quant_matrix, int *skip, int *dc_level){ const uint8_t *scantable = s->permutated_scantable; int level, ret, map = 0; memset(s->wblocks, 0, s->wblocks_size); for (int i = 0; i < 64; i++) { int16_t *block = s->wblocks + scantable[i]; for (int j = 0; j < s->blocks_w;) { if (*skip > 0) { int rskip; rskip = FFMIN(*skip, s->blocks_w - j); j += rskip; if (i == 0) { for (int k = 0; k < rskip; k++) block[64 * k] = *dc_level * quant_matrix[0]; } block += rskip * 64; *skip -= rskip; } else { ret = read_code(gb, skip, &level, &map, s->flags & 1); if (ret < 0) return ret; if (i == 0) *dc_level += level; block[0] = (i == 0 ? *dc_level : level) * quant_matrix[i]; block += 64; j++; } } } return 0;} static int decode_inter_blocks(AGMContext *s, GetBitContext *gb, const int *quant_matrix, int *skip, int *map){ const uint8_t *scantable = s->permutated_scantable; int level, ret; memset(s->wblocks, 0, s->wblocks_size); memset(s->map, 0, s->map_size); for (int i = 0; i < 64; i++) { int16_t *block = s->wblocks + scantable[i]; for (int j = 0; j < s->blocks_w;) { if (*skip > 0) { int rskip; rskip = FFMIN(*skip, s->blocks_w - j); j += rskip; block += rskip * 64; *skip -= rskip; } else { ret = read_code(gb, skip, &level, &map[j], s->flags & 1); if (ret < 0) return ret; block[0] = level * quant_matrix[i]; block += 64; j++; } } } return 0;} static int decode_intra_block(AGMContext *s, GetBitContext *gb, const int *quant_matrix, int *skip, int *dc_level){ const uint8_t *scantable = s->permutated_scantable; const int offset = s->plus ? 0 : 1024; int16_t *block = s->block; int level, ret, map = 0; memset(block, 0, sizeof(s->block)); if (*skip > 0) { (*skip)--; } else { ret = read_code(gb, skip, &level, &map, s->flags & 1); if (ret < 0) return ret; *dc_level += level; } block[scantable[0]] = offset + *dc_level * quant_matrix[0]; for (int i = 1; i < 64;) { if (*skip > 0) { int rskip; rskip = FFMIN(*skip, 64 - i); i += rskip; *skip -= rskip; } else { ret = read_code(gb, skip, &level, &map, s->flags & 1); if (ret < 0) return ret; block[scantable[i]] = level * quant_matrix[i]; i++; } } return 0;} static int decode_intra_plane(AGMContext *s, GetBitContext *gb, int size, const int *quant_matrix, AVFrame *frame, int plane){ int ret, skip = 0, dc_level = 0; const int offset = s->plus ? 0 : 1024; if ((ret = init_get_bits8(gb, s->gbyte.buffer, size)) < 0) return ret; if (s->flags & 1) { av_fast_padded_malloc(&s->wblocks, &s->wblocks_size, 64 * s->blocks_w * sizeof(*s->wblocks)); if (!s->wblocks) return AVERROR(ENOMEM); for (int y = 0; y < s->blocks_h; y++) { ret = decode_intra_blocks(s, gb, quant_matrix, &skip, &dc_level); if (ret < 0) return ret; for (int x = 0; x < s->blocks_w; x++) { s->wblocks[64 * x] += offset; s->idsp.idct_put(frame->data[plane] + (s->blocks_h - 1 - y) * 8 * frame->linesize[plane] + x * 8, frame->linesize[plane], s->wblocks + 64 * x); } } } else { for (int y = 0; y < s->blocks_h; y++) { for (int x = 0; x < s->blocks_w; x++) { ret = decode_intra_block(s, gb, quant_matrix, &skip, &dc_level); if (ret < 0) return ret; s->idsp.idct_put(frame->data[plane] + (s->blocks_h - 1 - y) * 8 * frame->linesize[plane] + x * 8, frame->linesize[plane], s->block); } } } align_get_bits(gb); if (get_bits_left(gb) < 0) av_log(s->avctx, AV_LOG_WARNING, "overread\n"); if (get_bits_left(gb) > 0) av_log(s->avctx, AV_LOG_WARNING, "underread: %d\n", get_bits_left(gb)); return 0;} static int decode_inter_block(AGMContext *s, GetBitContext *gb, const int *quant_matrix, int *skip, int *map){ const uint8_t *scantable = s->permutated_scantable; int16_t *block = s->block; int level, ret; memset(block, 0, sizeof(s->block)); for (int i = 0; i < 64;) { if (*skip > 0) { int rskip; rskip = FFMIN(*skip, 64 - i); i += rskip; *skip -= rskip; } else { ret = read_code(gb, skip, &level, map, s->flags & 1); if (ret < 0) return ret; block[scantable[i]] = level * quant_matrix[i]; i++; } } return 0;} static int decode_inter_plane(AGMContext *s, GetBitContext *gb, int size, const int *quant_matrix, AVFrame *frame, AVFrame *prev, int plane){ int ret, skip = 0; if ((ret = init_get_bits8(gb, s->gbyte.buffer, size)) < 0) return ret; if (s->flags == 3) { av_fast_padded_malloc(&s->wblocks, &s->wblocks_size, 64 * s->blocks_w * sizeof(*s->wblocks)); if (!s->wblocks) return AVERROR(ENOMEM); av_fast_padded_malloc(&s->map, &s->map_size, s->blocks_w * sizeof(*s->map)); if (!s->map) return AVERROR(ENOMEM); for (int y = 0; y < s->blocks_h; y++) { ret = decode_inter_blocks(s, gb, quant_matrix, &skip, s->map); if (ret < 0) return ret; for (int x = 0; x < s->blocks_w; x++) { int shift = plane == 0; int mvpos = (y >> shift) * (s->blocks_w >> shift) + (x >> shift); int orig_mv_x = s->mvectors[mvpos].x; int mv_x = s->mvectors[mvpos].x / (1 + !shift); int mv_y = s->mvectors[mvpos].y / (1 + !shift); int h = s->avctx->coded_height >> !shift; int w = s->avctx->coded_width >> !shift; int map = s->map[x]; if (orig_mv_x >= -32) { if (y * 8 + mv_y < 0 || y * 8 + mv_y + 8 > h || x * 8 + mv_x < 0 || x * 8 + mv_x + 8 > w) return AVERROR_INVALIDDATA; copy_block8(frame->data[plane] + (s->blocks_h - 1 - y) * 8 * frame->linesize[plane] + x * 8, prev->data[plane] + ((s->blocks_h - 1 - y) * 8 - mv_y) * prev->linesize[plane] + (x * 8 + mv_x), frame->linesize[plane], prev->linesize[plane], 8); if (map) { s->idsp.idct(s->wblocks + x * 64); for (int i = 0; i < 64; i++) s->wblocks[i + x * 64] = (s->wblocks[i + x * 64] + 1) & 0xFFFC; s->idsp.add_pixels_clamped(&s->wblocks[x*64], frame->data[plane] + (s->blocks_h - 1 - y) * 8 * frame->linesize[plane] + x * 8, frame->linesize[plane]); } } else if (map) { s->idsp.idct_put(frame->data[plane] + (s->blocks_h - 1 - y) * 8 * frame->linesize[plane] + x * 8, frame->linesize[plane], s->wblocks + x * 64); } } } } else if (s->flags & 2) { for (int y = 0; y < s->blocks_h; y++) { for (int x = 0; x < s->blocks_w; x++) { int shift = plane == 0; int mvpos = (y >> shift) * (s->blocks_w >> shift) + (x >> shift); int orig_mv_x = s->mvectors[mvpos].x; int mv_x = s->mvectors[mvpos].x / (1 + !shift); int mv_y = s->mvectors[mvpos].y / (1 + !shift); int h = s->avctx->coded_height >> !shift; int w = s->avctx->coded_width >> !shift; int map = 0; ret = decode_inter_block(s, gb, quant_matrix, &skip, &map); if (ret < 0) return ret; if (orig_mv_x >= -32) { if (y * 8 + mv_y < 0 || y * 8 + mv_y + 8 > h || x * 8 + mv_x < 0 || x * 8 + mv_x + 8 > w) return AVERROR_INVALIDDATA; copy_block8(frame->data[plane] + (s->blocks_h - 1 - y) * 8 * frame->linesize[plane] + x * 8, prev->data[plane] + ((s->blocks_h - 1 - y) * 8 - mv_y) * prev->linesize[plane] + (x * 8 + mv_x), frame->linesize[plane], prev->linesize[plane], 8); if (map) { s->idsp.idct(s->block); for (int i = 0; i < 64; i++) s->block[i] = (s->block[i] + 1) & 0xFFFC; s->idsp.add_pixels_clamped(s->block, frame->data[plane] + (s->blocks_h - 1 - y) * 8 * frame->linesize[plane] + x * 8, frame->linesize[plane]); } } else if (map) { s->idsp.idct_put(frame->data[plane] + (s->blocks_h - 1 - y) * 8 * frame->linesize[plane] + x * 8, frame->linesize[plane], s->block); } } } } else if (s->flags & 1) { av_fast_padded_malloc(&s->wblocks, &s->wblocks_size, 64 * s->blocks_w * sizeof(*s->wblocks)); if (!s->wblocks) return AVERROR(ENOMEM); av_fast_padded_malloc(&s->map, &s->map_size, s->blocks_w * sizeof(*s->map)); if (!s->map) return AVERROR(ENOMEM); for (int y = 0; y < s->blocks_h; y++) { ret = decode_inter_blocks(s, gb, quant_matrix, &skip, s->map); if (ret < 0) return ret; for (int x = 0; x < s->blocks_w; x++) { if (!s->map[x]) continue; s->idsp.idct_add(frame->data[plane] + (s->blocks_h - 1 - y) * 8 * frame->linesize[plane] + x * 8, frame->linesize[plane], s->wblocks + 64 * x); } } } else { for (int y = 0; y < s->blocks_h; y++) { for (int x = 0; x < s->blocks_w; x++) { int map = 0; ret = decode_inter_block(s, gb, quant_matrix, &skip, &map); if (ret < 0) return ret; if (!map)Lines 1–500 of 1286. Load more
/* * Amuse Graphics Movie decoder * * Copyright (c) 2018 Paul B Mahol * * This file is part of FFmpeg. * * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include <string.h> #define BITSTREAM_READER_LE #include "libavutil/mem.h" #include "libavutil/mem_internal.h" #include "avcodec.h" #include "bytestream.h" #include "codec_internal.h" #include "copy_block.h" #include "decode.h" #include "get_bits.h" #include "idctdsp.h" #include "jpegquanttables.h" typedef struct MotionVector { int16_t x, y; } MotionVector; typedef struct AGMContext { const AVClass *class; AVCodecContext *avctx; GetBitContext gb; GetByteContext gbyte; int key_frame; int bitstream_size; int compression; int blocks_w; int blocks_h; int size[3]; int plus; int dct; int rgb; unsigned flags; unsigned fflags; uint8_t *output; unsigned padded_output_size; unsigned output_size; MotionVector *mvectors; unsigned mvectors_size; VLC vlc; AVFrame *prev_frame; int luma_quant_matrix[64]; int chroma_quant_matrix[64]; uint8_t permutated_scantable[64]; DECLARE_ALIGNED(32, int16_t, block)[64]; int16_t *wblocks; unsigned wblocks_size; int *map; unsigned map_size; IDCTDSPContext idsp; } AGMContext; static int read_code(GetBitContext *gb, int *oskip, int *level, int *map, int mode) { int len = 0, skip = 0, max; if (get_bits_left(gb) < 2) return AVERROR_INVALIDDATA; if (show_bits(gb, 2)) { switch (show_bits(gb, 4)) { case 1: case 9: len = 1; skip = 3; break; case 2: len = 3; skip = 4; break; case 3: len = 7; skip = 4; break; case 5: case 13: len = 2; skip = 3; break; case 6: len = 4; skip = 4; break; case 7: len = 8; skip = 4; break; case 10: len = 5; skip = 4; break; case 11: len = 9; skip = 4; break; case 14: len = 6; skip = 4; break; case 15: len = ((show_bits(gb, 5) & 0x10) | 0xA0) >> 4; skip = 5; break; default: return AVERROR_INVALIDDATA; } skip_bits(gb, skip); *level = get_bits(gb, len); *map = 1; *oskip = 0; max = 1 << (len - 1); if (*level < max) *level = -(max + *level); } else if (show_bits(gb, 3) & 4) { skip_bits(gb, 3); if (mode == 1) { if (show_bits(gb, 4)) { if (show_bits(gb, 4) == 1) { skip_bits(gb, 4); *oskip = get_bits(gb, 16); } else { *oskip = get_bits(gb, 4); } } else { skip_bits(gb, 4); *oskip = get_bits(gb, 10); } } else if (mode == 0) { *oskip = get_bits(gb, 10); } *level = 0; } else { skip_bits(gb, 3); if (mode == 0) *oskip = get_bits(gb, 4); else if (mode == 1) *oskip = 0; *level = 0; } return 0; } static int decode_intra_blocks(AGMContext *s, GetBitContext *gb, const int *quant_matrix, int *skip, int *dc_level) { const uint8_t *scantable = s->permutated_scantable; int level, ret, map = 0; memset(s->wblocks, 0, s->wblocks_size); for (int i = 0; i < 64; i++) { int16_t *block = s->wblocks + scantable[i]; for (int j = 0; j < s->blocks_w;) { if (*skip > 0) { int rskip; rskip = FFMIN(*skip, s->blocks_w - j); j += rskip; if (i == 0) { for (int k = 0; k < rskip; k++) block[64 * k] = *dc_level * quant_matrix[0]; } block += rskip * 64; *skip -= rskip; } else { ret = read_code(gb, skip, &level, &map, s->flags & 1); if (ret < 0) return ret; if (i == 0) *dc_level += level; block[0] = (i == 0 ? *dc_level : level) * quant_matrix[i]; block += 64; j++; } } } return 0; } static int decode_inter_blocks(AGMContext *s, GetBitContext *gb, const int *quant_matrix, int *skip, int *map) { const uint8_t *scantable = s->permutated_scantable; int level, ret; memset(s->wblocks, 0, s->wblocks_size); memset(s->map, 0, s->map_size); for (int i = 0; i < 64; i++) { int16_t *block = s->wblocks + scantable[i]; for (int j = 0; j < s->blocks_w;) { if (*skip > 0) { int rskip; rskip = FFMIN(*skip, s->blocks_w - j); j += rskip; block += rskip * 64; *skip -= rskip; } else { ret = read_code(gb, skip, &level, &map[j], s->flags & 1); if (ret < 0) return ret; block[0] = level * quant_matrix[i]; block += 64; j++; } } } return 0; } static int decode_intra_block(AGMContext *s, GetBitContext *gb, const int *quant_matrix, int *skip, int *dc_level) { const uint8_t *scantable = s->permutated_scantable; const int offset = s->plus ? 0 : 1024; int16_t *block = s->block; int level, ret, map = 0; memset(block, 0, sizeof(s->block)); if (*skip > 0) { (*skip)--; } else { ret = read_code(gb, skip, &level, &map, s->flags & 1); if (ret < 0) return ret; *dc_level += level; } block[scantable[0]] = offset + *dc_level * quant_matrix[0]; for (int i = 1; i < 64;) { if (*skip > 0) { int rskip; rskip = FFMIN(*skip, 64 - i); i += rskip; *skip -= rskip; } else { ret = read_code(gb, skip, &level, &map, s->flags & 1); if (ret < 0) return ret; block[scantable[i]] = level * quant_matrix[i]; i++; } } return 0; } static int decode_intra_plane(AGMContext *s, GetBitContext *gb, int size, const int *quant_matrix, AVFrame *frame, int plane) { int ret, skip = 0, dc_level = 0; const int offset = s->plus ? 0 : 1024; if ((ret = init_get_bits8(gb, s->gbyte.buffer, size)) < 0) return ret; if (s->flags & 1) { av_fast_padded_malloc(&s->wblocks, &s->wblocks_size, 64 * s->blocks_w * sizeof(*s->wblocks)); if (!s->wblocks) return AVERROR(ENOMEM); for (int y = 0; y < s->blocks_h; y++) { ret = decode_intra_blocks(s, gb, quant_matrix, &skip, &dc_level); if (ret < 0) return ret; for (int x = 0; x < s->blocks_w; x++) { s->wblocks[64 * x] += offset; s->idsp.idct_put(frame->data[plane] + (s->blocks_h - 1 - y) * 8 * frame->linesize[plane] + x * 8, frame->linesize[plane], s->wblocks + 64 * x); } } } else { for (int y = 0; y < s->blocks_h; y++) { for (int x = 0; x < s->blocks_w; x++) { ret = decode_intra_block(s, gb, quant_matrix, &skip, &dc_level); if (ret < 0) return ret; s->idsp.idct_put(frame->data[plane] + (s->blocks_h - 1 - y) * 8 * frame->linesize[plane] + x * 8, frame->linesize[plane], s->block); } } } align_get_bits(gb); if (get_bits_left(gb) < 0) av_log(s->avctx, AV_LOG_WARNING, "overread\n"); if (get_bits_left(gb) > 0) av_log(s->avctx, AV_LOG_WARNING, "underread: %d\n", get_bits_left(gb)); return 0; } static int decode_inter_block(AGMContext *s, GetBitContext *gb, const int *quant_matrix, int *skip, int *map) { const uint8_t *scantable = s->permutated_scantable; int16_t *block = s->block; int level, ret; memset(block, 0, sizeof(s->block)); for (int i = 0; i < 64;) { if (*skip > 0) { int rskip; rskip = FFMIN(*skip, 64 - i); i += rskip; *skip -= rskip; } else { ret = read_code(gb, skip, &level, map, s->flags & 1); if (ret < 0) return ret; block[scantable[i]] = level * quant_matrix[i]; i++; } } return 0; } static int decode_inter_plane(AGMContext *s, GetBitContext *gb, int size, const int *quant_matrix, AVFrame *frame, AVFrame *prev, int plane) { int ret, skip = 0; if ((ret = init_get_bits8(gb, s->gbyte.buffer, size)) < 0) return ret; if (s->flags == 3) { av_fast_padded_malloc(&s->wblocks, &s->wblocks_size, 64 * s->blocks_w * sizeof(*s->wblocks)); if (!s->wblocks) return AVERROR(ENOMEM); av_fast_padded_malloc(&s->map, &s->map_size, s->blocks_w * sizeof(*s->map)); if (!s->map) return AVERROR(ENOMEM); for (int y = 0; y < s->blocks_h; y++) { ret = decode_inter_blocks(s, gb, quant_matrix, &skip, s->map); if (ret < 0) return ret; for (int x = 0; x < s->blocks_w; x++) { int shift = plane == 0; int mvpos = (y >> shift) * (s->blocks_w >> shift) + (x >> shift); int orig_mv_x = s->mvectors[mvpos].x; int mv_x = s->mvectors[mvpos].x / (1 + !shift); int mv_y = s->mvectors[mvpos].y / (1 + !shift); int h = s->avctx->coded_height >> !shift; int w = s->avctx->coded_width >> !shift; int map = s->map[x]; if (orig_mv_x >= -32) { if (y * 8 + mv_y < 0 || y * 8 + mv_y + 8 > h || x * 8 + mv_x < 0 || x * 8 + mv_x + 8 > w) return AVERROR_INVALIDDATA; copy_block8(frame->data[plane] + (s->blocks_h - 1 - y) * 8 * frame->linesize[plane] + x * 8, prev->data[plane] + ((s->blocks_h - 1 - y) * 8 - mv_y) * prev->linesize[plane] + (x * 8 + mv_x), frame->linesize[plane], prev->linesize[plane], 8); if (map) { s->idsp.idct(s->wblocks + x * 64); for (int i = 0; i < 64; i++) s->wblocks[i + x * 64] = (s->wblocks[i + x * 64] + 1) & 0xFFFC; s->idsp.add_pixels_clamped(&s->wblocks[x*64], frame->data[plane] + (s->blocks_h - 1 - y) * 8 * frame->linesize[plane] + x * 8, frame->linesize[plane]); } } else if (map) { s->idsp.idct_put(frame->data[plane] + (s->blocks_h - 1 - y) * 8 * frame->linesize[plane] + x * 8, frame->linesize[plane], s->wblocks + x * 64); } } } } else if (s->flags & 2) { for (int y = 0; y < s->blocks_h; y++) { for (int x = 0; x < s->blocks_w; x++) { int shift = plane == 0; int mvpos = (y >> shift) * (s->blocks_w >> shift) + (x >> shift); int orig_mv_x = s->mvectors[mvpos].x; int mv_x = s->mvectors[mvpos].x / (1 + !shift); int mv_y = s->mvectors[mvpos].y / (1 + !shift); int h = s->avctx->coded_height >> !shift; int w = s->avctx->coded_width >> !shift; int map = 0; ret = decode_inter_block(s, gb, quant_matrix, &skip, &map); if (ret < 0) return ret; if (orig_mv_x >= -32) { if (y * 8 + mv_y < 0 || y * 8 + mv_y + 8 > h || x * 8 + mv_x < 0 || x * 8 + mv_x + 8 > w) return AVERROR_INVALIDDATA; copy_block8(frame->data[plane] + (s->blocks_h - 1 - y) * 8 * frame->linesize[plane] + x * 8, prev->data[plane] + ((s->blocks_h - 1 - y) * 8 - mv_y) * prev->linesize[plane] + (x * 8 + mv_x), frame->linesize[plane], prev->linesize[plane], 8); if (map) { s->idsp.idct(s->block); for (int i = 0; i < 64; i++) s->block[i] = (s->block[i] + 1) & 0xFFFC; s->idsp.add_pixels_clamped(s->block, frame->data[plane] + (s->blocks_h - 1 - y) * 8 * frame->linesize[plane] + x * 8, frame->linesize[plane]); } } else if (map) { s->idsp.idct_put(frame->data[plane] + (s->blocks_h - 1 - y) * 8 * frame->linesize[plane] + x * 8, frame->linesize[plane], s->block); } } } } else if (s->flags & 1) { av_fast_padded_malloc(&s->wblocks, &s->wblocks_size, 64 * s->blocks_w * sizeof(*s->wblocks)); if (!s->wblocks) return AVERROR(ENOMEM); av_fast_padded_malloc(&s->map, &s->map_size, s->blocks_w * sizeof(*s->map)); if (!s->map) return AVERROR(ENOMEM); for (int y = 0; y < s->blocks_h; y++) { ret = decode_inter_blocks(s, gb, quant_matrix, &skip, s->map); if (ret < 0) return ret; for (int x = 0; x < s->blocks_w; x++) { if (!s->map[x]) continue; s->idsp.idct_add(frame->data[plane] + (s->blocks_h - 1 - y) * 8 * frame->linesize[plane] + x * 8, frame->linesize[plane], s->wblocks + 64 * x); } } } else { for (int y = 0; y < s->blocks_h; y++) { for (int x = 0; x < s->blocks_w; x++) { int map = 0; ret = decode_inter_block(s, gb, quant_matrix, &skip, &map); if (ret < 0) return ret; if (!map)