1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * Amuse Graphics Movie decoder 3cabdff1aSopenharmony_ci * 4cabdff1aSopenharmony_ci * Copyright (c) 2018 Paul B Mahol 5cabdff1aSopenharmony_ci * 6cabdff1aSopenharmony_ci * This file is part of FFmpeg. 7cabdff1aSopenharmony_ci * 8cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 9cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 10cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 11cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 12cabdff1aSopenharmony_ci * 13cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 14cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 15cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16cabdff1aSopenharmony_ci * Lesser General Public License for more details. 17cabdff1aSopenharmony_ci * 18cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 19cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software 20cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 21cabdff1aSopenharmony_ci */ 22cabdff1aSopenharmony_ci 23cabdff1aSopenharmony_ci#include <stdio.h> 24cabdff1aSopenharmony_ci#include <stdlib.h> 25cabdff1aSopenharmony_ci#include <string.h> 26cabdff1aSopenharmony_ci 27cabdff1aSopenharmony_ci#define BITSTREAM_READER_LE 28cabdff1aSopenharmony_ci 29cabdff1aSopenharmony_ci#include "libavutil/mem_internal.h" 30cabdff1aSopenharmony_ci 31cabdff1aSopenharmony_ci#include "avcodec.h" 32cabdff1aSopenharmony_ci#include "bytestream.h" 33cabdff1aSopenharmony_ci#include "codec_internal.h" 34cabdff1aSopenharmony_ci#include "copy_block.h" 35cabdff1aSopenharmony_ci#include "get_bits.h" 36cabdff1aSopenharmony_ci#include "idctdsp.h" 37cabdff1aSopenharmony_ci#include "internal.h" 38cabdff1aSopenharmony_ci 39cabdff1aSopenharmony_cistatic const uint8_t unscaled_luma[64] = { 40cabdff1aSopenharmony_ci 16, 11, 10, 16, 24, 40, 51, 61, 12, 12, 14, 19, 41cabdff1aSopenharmony_ci 26, 58, 60, 55, 14, 13, 16, 24, 40, 57, 69, 56, 42cabdff1aSopenharmony_ci 14, 17, 22, 29, 51, 87, 80, 62, 18, 22, 37, 56, 43cabdff1aSopenharmony_ci 68,109,103, 77, 24, 35, 55, 64, 81,104,113, 92, 44cabdff1aSopenharmony_ci 49, 64, 78, 87,103,121,120,101, 72, 92, 95, 98, 45cabdff1aSopenharmony_ci 112,100,103,99 46cabdff1aSopenharmony_ci}; 47cabdff1aSopenharmony_ci 48cabdff1aSopenharmony_cistatic const uint8_t unscaled_chroma[64] = { 49cabdff1aSopenharmony_ci 17, 18, 24, 47, 99, 99, 99, 99, 18, 21, 26, 66, 50cabdff1aSopenharmony_ci 99, 99, 99, 99, 24, 26, 56, 99, 99, 99, 99, 99, 51cabdff1aSopenharmony_ci 47, 66, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 52cabdff1aSopenharmony_ci 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 53cabdff1aSopenharmony_ci 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 54cabdff1aSopenharmony_ci 99, 99, 99, 99 55cabdff1aSopenharmony_ci}; 56cabdff1aSopenharmony_ci 57cabdff1aSopenharmony_citypedef struct MotionVector { 58cabdff1aSopenharmony_ci int16_t x, y; 59cabdff1aSopenharmony_ci} MotionVector; 60cabdff1aSopenharmony_ci 61cabdff1aSopenharmony_citypedef struct AGMContext { 62cabdff1aSopenharmony_ci const AVClass *class; 63cabdff1aSopenharmony_ci AVCodecContext *avctx; 64cabdff1aSopenharmony_ci GetBitContext gb; 65cabdff1aSopenharmony_ci GetByteContext gbyte; 66cabdff1aSopenharmony_ci 67cabdff1aSopenharmony_ci int key_frame; 68cabdff1aSopenharmony_ci int bitstream_size; 69cabdff1aSopenharmony_ci int compression; 70cabdff1aSopenharmony_ci int blocks_w; 71cabdff1aSopenharmony_ci int blocks_h; 72cabdff1aSopenharmony_ci int size[3]; 73cabdff1aSopenharmony_ci int plus; 74cabdff1aSopenharmony_ci int dct; 75cabdff1aSopenharmony_ci int rgb; 76cabdff1aSopenharmony_ci unsigned flags; 77cabdff1aSopenharmony_ci unsigned fflags; 78cabdff1aSopenharmony_ci 79cabdff1aSopenharmony_ci uint8_t *output; 80cabdff1aSopenharmony_ci unsigned padded_output_size; 81cabdff1aSopenharmony_ci unsigned output_size; 82cabdff1aSopenharmony_ci 83cabdff1aSopenharmony_ci MotionVector *mvectors; 84cabdff1aSopenharmony_ci unsigned mvectors_size; 85cabdff1aSopenharmony_ci 86cabdff1aSopenharmony_ci VLC vlc; 87cabdff1aSopenharmony_ci 88cabdff1aSopenharmony_ci AVFrame *prev_frame; 89cabdff1aSopenharmony_ci 90cabdff1aSopenharmony_ci int luma_quant_matrix[64]; 91cabdff1aSopenharmony_ci int chroma_quant_matrix[64]; 92cabdff1aSopenharmony_ci 93cabdff1aSopenharmony_ci ScanTable scantable; 94cabdff1aSopenharmony_ci DECLARE_ALIGNED(32, int16_t, block)[64]; 95cabdff1aSopenharmony_ci 96cabdff1aSopenharmony_ci int16_t *wblocks; 97cabdff1aSopenharmony_ci unsigned wblocks_size; 98cabdff1aSopenharmony_ci 99cabdff1aSopenharmony_ci int *map; 100cabdff1aSopenharmony_ci unsigned map_size; 101cabdff1aSopenharmony_ci 102cabdff1aSopenharmony_ci IDCTDSPContext idsp; 103cabdff1aSopenharmony_ci} AGMContext; 104cabdff1aSopenharmony_ci 105cabdff1aSopenharmony_cistatic int read_code(GetBitContext *gb, int *oskip, int *level, int *map, int mode) 106cabdff1aSopenharmony_ci{ 107cabdff1aSopenharmony_ci int len = 0, skip = 0, max; 108cabdff1aSopenharmony_ci 109cabdff1aSopenharmony_ci if (get_bits_left(gb) < 2) 110cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 111cabdff1aSopenharmony_ci 112cabdff1aSopenharmony_ci if (show_bits(gb, 2)) { 113cabdff1aSopenharmony_ci switch (show_bits(gb, 4)) { 114cabdff1aSopenharmony_ci case 1: 115cabdff1aSopenharmony_ci case 9: 116cabdff1aSopenharmony_ci len = 1; 117cabdff1aSopenharmony_ci skip = 3; 118cabdff1aSopenharmony_ci break; 119cabdff1aSopenharmony_ci case 2: 120cabdff1aSopenharmony_ci len = 3; 121cabdff1aSopenharmony_ci skip = 4; 122cabdff1aSopenharmony_ci break; 123cabdff1aSopenharmony_ci case 3: 124cabdff1aSopenharmony_ci len = 7; 125cabdff1aSopenharmony_ci skip = 4; 126cabdff1aSopenharmony_ci break; 127cabdff1aSopenharmony_ci case 5: 128cabdff1aSopenharmony_ci case 13: 129cabdff1aSopenharmony_ci len = 2; 130cabdff1aSopenharmony_ci skip = 3; 131cabdff1aSopenharmony_ci break; 132cabdff1aSopenharmony_ci case 6: 133cabdff1aSopenharmony_ci len = 4; 134cabdff1aSopenharmony_ci skip = 4; 135cabdff1aSopenharmony_ci break; 136cabdff1aSopenharmony_ci case 7: 137cabdff1aSopenharmony_ci len = 8; 138cabdff1aSopenharmony_ci skip = 4; 139cabdff1aSopenharmony_ci break; 140cabdff1aSopenharmony_ci case 10: 141cabdff1aSopenharmony_ci len = 5; 142cabdff1aSopenharmony_ci skip = 4; 143cabdff1aSopenharmony_ci break; 144cabdff1aSopenharmony_ci case 11: 145cabdff1aSopenharmony_ci len = 9; 146cabdff1aSopenharmony_ci skip = 4; 147cabdff1aSopenharmony_ci break; 148cabdff1aSopenharmony_ci case 14: 149cabdff1aSopenharmony_ci len = 6; 150cabdff1aSopenharmony_ci skip = 4; 151cabdff1aSopenharmony_ci break; 152cabdff1aSopenharmony_ci case 15: 153cabdff1aSopenharmony_ci len = ((show_bits(gb, 5) & 0x10) | 0xA0) >> 4; 154cabdff1aSopenharmony_ci skip = 5; 155cabdff1aSopenharmony_ci break; 156cabdff1aSopenharmony_ci default: 157cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 158cabdff1aSopenharmony_ci } 159cabdff1aSopenharmony_ci 160cabdff1aSopenharmony_ci skip_bits(gb, skip); 161cabdff1aSopenharmony_ci *level = get_bits(gb, len); 162cabdff1aSopenharmony_ci *map = 1; 163cabdff1aSopenharmony_ci *oskip = 0; 164cabdff1aSopenharmony_ci max = 1 << (len - 1); 165cabdff1aSopenharmony_ci if (*level < max) 166cabdff1aSopenharmony_ci *level = -(max + *level); 167cabdff1aSopenharmony_ci } else if (show_bits(gb, 3) & 4) { 168cabdff1aSopenharmony_ci skip_bits(gb, 3); 169cabdff1aSopenharmony_ci if (mode == 1) { 170cabdff1aSopenharmony_ci if (show_bits(gb, 4)) { 171cabdff1aSopenharmony_ci if (show_bits(gb, 4) == 1) { 172cabdff1aSopenharmony_ci skip_bits(gb, 4); 173cabdff1aSopenharmony_ci *oskip = get_bits(gb, 16); 174cabdff1aSopenharmony_ci } else { 175cabdff1aSopenharmony_ci *oskip = get_bits(gb, 4); 176cabdff1aSopenharmony_ci } 177cabdff1aSopenharmony_ci } else { 178cabdff1aSopenharmony_ci skip_bits(gb, 4); 179cabdff1aSopenharmony_ci *oskip = get_bits(gb, 10); 180cabdff1aSopenharmony_ci } 181cabdff1aSopenharmony_ci } else if (mode == 0) { 182cabdff1aSopenharmony_ci *oskip = get_bits(gb, 10); 183cabdff1aSopenharmony_ci } 184cabdff1aSopenharmony_ci *level = 0; 185cabdff1aSopenharmony_ci } else { 186cabdff1aSopenharmony_ci skip_bits(gb, 3); 187cabdff1aSopenharmony_ci if (mode == 0) 188cabdff1aSopenharmony_ci *oskip = get_bits(gb, 4); 189cabdff1aSopenharmony_ci else if (mode == 1) 190cabdff1aSopenharmony_ci *oskip = 0; 191cabdff1aSopenharmony_ci *level = 0; 192cabdff1aSopenharmony_ci } 193cabdff1aSopenharmony_ci 194cabdff1aSopenharmony_ci return 0; 195cabdff1aSopenharmony_ci} 196cabdff1aSopenharmony_ci 197cabdff1aSopenharmony_cistatic int decode_intra_blocks(AGMContext *s, GetBitContext *gb, 198cabdff1aSopenharmony_ci const int *quant_matrix, int *skip, int *dc_level) 199cabdff1aSopenharmony_ci{ 200cabdff1aSopenharmony_ci const uint8_t *scantable = s->scantable.permutated; 201cabdff1aSopenharmony_ci int level, ret, map = 0; 202cabdff1aSopenharmony_ci 203cabdff1aSopenharmony_ci memset(s->wblocks, 0, s->wblocks_size); 204cabdff1aSopenharmony_ci 205cabdff1aSopenharmony_ci for (int i = 0; i < 64; i++) { 206cabdff1aSopenharmony_ci int16_t *block = s->wblocks + scantable[i]; 207cabdff1aSopenharmony_ci 208cabdff1aSopenharmony_ci for (int j = 0; j < s->blocks_w;) { 209cabdff1aSopenharmony_ci if (*skip > 0) { 210cabdff1aSopenharmony_ci int rskip; 211cabdff1aSopenharmony_ci 212cabdff1aSopenharmony_ci rskip = FFMIN(*skip, s->blocks_w - j); 213cabdff1aSopenharmony_ci j += rskip; 214cabdff1aSopenharmony_ci if (i == 0) { 215cabdff1aSopenharmony_ci for (int k = 0; k < rskip; k++) 216cabdff1aSopenharmony_ci block[64 * k] = *dc_level * quant_matrix[0]; 217cabdff1aSopenharmony_ci } 218cabdff1aSopenharmony_ci block += rskip * 64; 219cabdff1aSopenharmony_ci *skip -= rskip; 220cabdff1aSopenharmony_ci } else { 221cabdff1aSopenharmony_ci ret = read_code(gb, skip, &level, &map, s->flags & 1); 222cabdff1aSopenharmony_ci if (ret < 0) 223cabdff1aSopenharmony_ci return ret; 224cabdff1aSopenharmony_ci 225cabdff1aSopenharmony_ci if (i == 0) 226cabdff1aSopenharmony_ci *dc_level += level; 227cabdff1aSopenharmony_ci 228cabdff1aSopenharmony_ci block[0] = (i == 0 ? *dc_level : level) * quant_matrix[i]; 229cabdff1aSopenharmony_ci block += 64; 230cabdff1aSopenharmony_ci j++; 231cabdff1aSopenharmony_ci } 232cabdff1aSopenharmony_ci } 233cabdff1aSopenharmony_ci } 234cabdff1aSopenharmony_ci 235cabdff1aSopenharmony_ci return 0; 236cabdff1aSopenharmony_ci} 237cabdff1aSopenharmony_ci 238cabdff1aSopenharmony_cistatic int decode_inter_blocks(AGMContext *s, GetBitContext *gb, 239cabdff1aSopenharmony_ci const int *quant_matrix, int *skip, 240cabdff1aSopenharmony_ci int *map) 241cabdff1aSopenharmony_ci{ 242cabdff1aSopenharmony_ci const uint8_t *scantable = s->scantable.permutated; 243cabdff1aSopenharmony_ci int level, ret; 244cabdff1aSopenharmony_ci 245cabdff1aSopenharmony_ci memset(s->wblocks, 0, s->wblocks_size); 246cabdff1aSopenharmony_ci memset(s->map, 0, s->map_size); 247cabdff1aSopenharmony_ci 248cabdff1aSopenharmony_ci for (int i = 0; i < 64; i++) { 249cabdff1aSopenharmony_ci int16_t *block = s->wblocks + scantable[i]; 250cabdff1aSopenharmony_ci 251cabdff1aSopenharmony_ci for (int j = 0; j < s->blocks_w;) { 252cabdff1aSopenharmony_ci if (*skip > 0) { 253cabdff1aSopenharmony_ci int rskip; 254cabdff1aSopenharmony_ci 255cabdff1aSopenharmony_ci rskip = FFMIN(*skip, s->blocks_w - j); 256cabdff1aSopenharmony_ci j += rskip; 257cabdff1aSopenharmony_ci block += rskip * 64; 258cabdff1aSopenharmony_ci *skip -= rskip; 259cabdff1aSopenharmony_ci } else { 260cabdff1aSopenharmony_ci ret = read_code(gb, skip, &level, &map[j], s->flags & 1); 261cabdff1aSopenharmony_ci if (ret < 0) 262cabdff1aSopenharmony_ci return ret; 263cabdff1aSopenharmony_ci 264cabdff1aSopenharmony_ci block[0] = level * quant_matrix[i]; 265cabdff1aSopenharmony_ci block += 64; 266cabdff1aSopenharmony_ci j++; 267cabdff1aSopenharmony_ci } 268cabdff1aSopenharmony_ci } 269cabdff1aSopenharmony_ci } 270cabdff1aSopenharmony_ci 271cabdff1aSopenharmony_ci return 0; 272cabdff1aSopenharmony_ci} 273cabdff1aSopenharmony_ci 274cabdff1aSopenharmony_cistatic int decode_intra_block(AGMContext *s, GetBitContext *gb, 275cabdff1aSopenharmony_ci const int *quant_matrix, int *skip, int *dc_level) 276cabdff1aSopenharmony_ci{ 277cabdff1aSopenharmony_ci const uint8_t *scantable = s->scantable.permutated; 278cabdff1aSopenharmony_ci const int offset = s->plus ? 0 : 1024; 279cabdff1aSopenharmony_ci int16_t *block = s->block; 280cabdff1aSopenharmony_ci int level, ret, map = 0; 281cabdff1aSopenharmony_ci 282cabdff1aSopenharmony_ci memset(block, 0, sizeof(s->block)); 283cabdff1aSopenharmony_ci 284cabdff1aSopenharmony_ci if (*skip > 0) { 285cabdff1aSopenharmony_ci (*skip)--; 286cabdff1aSopenharmony_ci } else { 287cabdff1aSopenharmony_ci ret = read_code(gb, skip, &level, &map, s->flags & 1); 288cabdff1aSopenharmony_ci if (ret < 0) 289cabdff1aSopenharmony_ci return ret; 290cabdff1aSopenharmony_ci *dc_level += level; 291cabdff1aSopenharmony_ci } 292cabdff1aSopenharmony_ci block[scantable[0]] = offset + *dc_level * quant_matrix[0]; 293cabdff1aSopenharmony_ci 294cabdff1aSopenharmony_ci for (int i = 1; i < 64;) { 295cabdff1aSopenharmony_ci if (*skip > 0) { 296cabdff1aSopenharmony_ci int rskip; 297cabdff1aSopenharmony_ci 298cabdff1aSopenharmony_ci rskip = FFMIN(*skip, 64 - i); 299cabdff1aSopenharmony_ci i += rskip; 300cabdff1aSopenharmony_ci *skip -= rskip; 301cabdff1aSopenharmony_ci } else { 302cabdff1aSopenharmony_ci ret = read_code(gb, skip, &level, &map, s->flags & 1); 303cabdff1aSopenharmony_ci if (ret < 0) 304cabdff1aSopenharmony_ci return ret; 305cabdff1aSopenharmony_ci 306cabdff1aSopenharmony_ci block[scantable[i]] = level * quant_matrix[i]; 307cabdff1aSopenharmony_ci i++; 308cabdff1aSopenharmony_ci } 309cabdff1aSopenharmony_ci } 310cabdff1aSopenharmony_ci 311cabdff1aSopenharmony_ci return 0; 312cabdff1aSopenharmony_ci} 313cabdff1aSopenharmony_ci 314cabdff1aSopenharmony_cistatic int decode_intra_plane(AGMContext *s, GetBitContext *gb, int size, 315cabdff1aSopenharmony_ci const int *quant_matrix, AVFrame *frame, 316cabdff1aSopenharmony_ci int plane) 317cabdff1aSopenharmony_ci{ 318cabdff1aSopenharmony_ci int ret, skip = 0, dc_level = 0; 319cabdff1aSopenharmony_ci const int offset = s->plus ? 0 : 1024; 320cabdff1aSopenharmony_ci 321cabdff1aSopenharmony_ci if ((ret = init_get_bits8(gb, s->gbyte.buffer, size)) < 0) 322cabdff1aSopenharmony_ci return ret; 323cabdff1aSopenharmony_ci 324cabdff1aSopenharmony_ci if (s->flags & 1) { 325cabdff1aSopenharmony_ci av_fast_padded_malloc(&s->wblocks, &s->wblocks_size, 326cabdff1aSopenharmony_ci 64 * s->blocks_w * sizeof(*s->wblocks)); 327cabdff1aSopenharmony_ci if (!s->wblocks) 328cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 329cabdff1aSopenharmony_ci 330cabdff1aSopenharmony_ci for (int y = 0; y < s->blocks_h; y++) { 331cabdff1aSopenharmony_ci ret = decode_intra_blocks(s, gb, quant_matrix, &skip, &dc_level); 332cabdff1aSopenharmony_ci if (ret < 0) 333cabdff1aSopenharmony_ci return ret; 334cabdff1aSopenharmony_ci 335cabdff1aSopenharmony_ci for (int x = 0; x < s->blocks_w; x++) { 336cabdff1aSopenharmony_ci s->wblocks[64 * x] += offset; 337cabdff1aSopenharmony_ci s->idsp.idct_put(frame->data[plane] + (s->blocks_h - 1 - y) * 8 * frame->linesize[plane] + x * 8, 338cabdff1aSopenharmony_ci frame->linesize[plane], s->wblocks + 64 * x); 339cabdff1aSopenharmony_ci } 340cabdff1aSopenharmony_ci } 341cabdff1aSopenharmony_ci } else { 342cabdff1aSopenharmony_ci for (int y = 0; y < s->blocks_h; y++) { 343cabdff1aSopenharmony_ci for (int x = 0; x < s->blocks_w; x++) { 344cabdff1aSopenharmony_ci ret = decode_intra_block(s, gb, quant_matrix, &skip, &dc_level); 345cabdff1aSopenharmony_ci if (ret < 0) 346cabdff1aSopenharmony_ci return ret; 347cabdff1aSopenharmony_ci 348cabdff1aSopenharmony_ci s->idsp.idct_put(frame->data[plane] + (s->blocks_h - 1 - y) * 8 * frame->linesize[plane] + x * 8, 349cabdff1aSopenharmony_ci frame->linesize[plane], s->block); 350cabdff1aSopenharmony_ci } 351cabdff1aSopenharmony_ci } 352cabdff1aSopenharmony_ci } 353cabdff1aSopenharmony_ci 354cabdff1aSopenharmony_ci align_get_bits(gb); 355cabdff1aSopenharmony_ci if (get_bits_left(gb) < 0) 356cabdff1aSopenharmony_ci av_log(s->avctx, AV_LOG_WARNING, "overread\n"); 357cabdff1aSopenharmony_ci if (get_bits_left(gb) > 0) 358cabdff1aSopenharmony_ci av_log(s->avctx, AV_LOG_WARNING, "underread: %d\n", get_bits_left(gb)); 359cabdff1aSopenharmony_ci 360cabdff1aSopenharmony_ci return 0; 361cabdff1aSopenharmony_ci} 362cabdff1aSopenharmony_ci 363cabdff1aSopenharmony_cistatic int decode_inter_block(AGMContext *s, GetBitContext *gb, 364cabdff1aSopenharmony_ci const int *quant_matrix, int *skip, 365cabdff1aSopenharmony_ci int *map) 366cabdff1aSopenharmony_ci{ 367cabdff1aSopenharmony_ci const uint8_t *scantable = s->scantable.permutated; 368cabdff1aSopenharmony_ci int16_t *block = s->block; 369cabdff1aSopenharmony_ci int level, ret; 370cabdff1aSopenharmony_ci 371cabdff1aSopenharmony_ci memset(block, 0, sizeof(s->block)); 372cabdff1aSopenharmony_ci 373cabdff1aSopenharmony_ci for (int i = 0; i < 64;) { 374cabdff1aSopenharmony_ci if (*skip > 0) { 375cabdff1aSopenharmony_ci int rskip; 376cabdff1aSopenharmony_ci 377cabdff1aSopenharmony_ci rskip = FFMIN(*skip, 64 - i); 378cabdff1aSopenharmony_ci i += rskip; 379cabdff1aSopenharmony_ci *skip -= rskip; 380cabdff1aSopenharmony_ci } else { 381cabdff1aSopenharmony_ci ret = read_code(gb, skip, &level, map, s->flags & 1); 382cabdff1aSopenharmony_ci if (ret < 0) 383cabdff1aSopenharmony_ci return ret; 384cabdff1aSopenharmony_ci 385cabdff1aSopenharmony_ci block[scantable[i]] = level * quant_matrix[i]; 386cabdff1aSopenharmony_ci i++; 387cabdff1aSopenharmony_ci } 388cabdff1aSopenharmony_ci } 389cabdff1aSopenharmony_ci 390cabdff1aSopenharmony_ci return 0; 391cabdff1aSopenharmony_ci} 392cabdff1aSopenharmony_ci 393cabdff1aSopenharmony_cistatic int decode_inter_plane(AGMContext *s, GetBitContext *gb, int size, 394cabdff1aSopenharmony_ci const int *quant_matrix, AVFrame *frame, 395cabdff1aSopenharmony_ci AVFrame *prev, int plane) 396cabdff1aSopenharmony_ci{ 397cabdff1aSopenharmony_ci int ret, skip = 0; 398cabdff1aSopenharmony_ci 399cabdff1aSopenharmony_ci if ((ret = init_get_bits8(gb, s->gbyte.buffer, size)) < 0) 400cabdff1aSopenharmony_ci return ret; 401cabdff1aSopenharmony_ci 402cabdff1aSopenharmony_ci if (s->flags == 3) { 403cabdff1aSopenharmony_ci av_fast_padded_malloc(&s->wblocks, &s->wblocks_size, 404cabdff1aSopenharmony_ci 64 * s->blocks_w * sizeof(*s->wblocks)); 405cabdff1aSopenharmony_ci if (!s->wblocks) 406cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 407cabdff1aSopenharmony_ci 408cabdff1aSopenharmony_ci av_fast_padded_malloc(&s->map, &s->map_size, 409cabdff1aSopenharmony_ci s->blocks_w * sizeof(*s->map)); 410cabdff1aSopenharmony_ci if (!s->map) 411cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 412cabdff1aSopenharmony_ci 413cabdff1aSopenharmony_ci for (int y = 0; y < s->blocks_h; y++) { 414cabdff1aSopenharmony_ci ret = decode_inter_blocks(s, gb, quant_matrix, &skip, s->map); 415cabdff1aSopenharmony_ci if (ret < 0) 416cabdff1aSopenharmony_ci return ret; 417cabdff1aSopenharmony_ci 418cabdff1aSopenharmony_ci for (int x = 0; x < s->blocks_w; x++) { 419cabdff1aSopenharmony_ci int shift = plane == 0; 420cabdff1aSopenharmony_ci int mvpos = (y >> shift) * (s->blocks_w >> shift) + (x >> shift); 421cabdff1aSopenharmony_ci int orig_mv_x = s->mvectors[mvpos].x; 422cabdff1aSopenharmony_ci int mv_x = s->mvectors[mvpos].x / (1 + !shift); 423cabdff1aSopenharmony_ci int mv_y = s->mvectors[mvpos].y / (1 + !shift); 424cabdff1aSopenharmony_ci int h = s->avctx->coded_height >> !shift; 425cabdff1aSopenharmony_ci int w = s->avctx->coded_width >> !shift; 426cabdff1aSopenharmony_ci int map = s->map[x]; 427cabdff1aSopenharmony_ci 428cabdff1aSopenharmony_ci if (orig_mv_x >= -32) { 429cabdff1aSopenharmony_ci if (y * 8 + mv_y < 0 || y * 8 + mv_y + 8 > h || 430cabdff1aSopenharmony_ci x * 8 + mv_x < 0 || x * 8 + mv_x + 8 > w) 431cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 432cabdff1aSopenharmony_ci 433cabdff1aSopenharmony_ci copy_block8(frame->data[plane] + (s->blocks_h - 1 - y) * 8 * frame->linesize[plane] + x * 8, 434cabdff1aSopenharmony_ci prev->data[plane] + ((s->blocks_h - 1 - y) * 8 - mv_y) * prev->linesize[plane] + (x * 8 + mv_x), 435cabdff1aSopenharmony_ci frame->linesize[plane], prev->linesize[plane], 8); 436cabdff1aSopenharmony_ci if (map) { 437cabdff1aSopenharmony_ci s->idsp.idct(s->wblocks + x * 64); 438cabdff1aSopenharmony_ci for (int i = 0; i < 64; i++) 439cabdff1aSopenharmony_ci s->wblocks[i + x * 64] = (s->wblocks[i + x * 64] + 1) & 0xFFFC; 440cabdff1aSopenharmony_ci s->idsp.add_pixels_clamped(&s->wblocks[x*64], frame->data[plane] + (s->blocks_h - 1 - y) * 8 * frame->linesize[plane] + x * 8, 441cabdff1aSopenharmony_ci frame->linesize[plane]); 442cabdff1aSopenharmony_ci } 443cabdff1aSopenharmony_ci } else if (map) { 444cabdff1aSopenharmony_ci s->idsp.idct_put(frame->data[plane] + (s->blocks_h - 1 - y) * 8 * frame->linesize[plane] + x * 8, 445cabdff1aSopenharmony_ci frame->linesize[plane], s->wblocks + x * 64); 446cabdff1aSopenharmony_ci } 447cabdff1aSopenharmony_ci } 448cabdff1aSopenharmony_ci } 449cabdff1aSopenharmony_ci } else if (s->flags & 2) { 450cabdff1aSopenharmony_ci for (int y = 0; y < s->blocks_h; y++) { 451cabdff1aSopenharmony_ci for (int x = 0; x < s->blocks_w; x++) { 452cabdff1aSopenharmony_ci int shift = plane == 0; 453cabdff1aSopenharmony_ci int mvpos = (y >> shift) * (s->blocks_w >> shift) + (x >> shift); 454cabdff1aSopenharmony_ci int orig_mv_x = s->mvectors[mvpos].x; 455cabdff1aSopenharmony_ci int mv_x = s->mvectors[mvpos].x / (1 + !shift); 456cabdff1aSopenharmony_ci int mv_y = s->mvectors[mvpos].y / (1 + !shift); 457cabdff1aSopenharmony_ci int h = s->avctx->coded_height >> !shift; 458cabdff1aSopenharmony_ci int w = s->avctx->coded_width >> !shift; 459cabdff1aSopenharmony_ci int map = 0; 460cabdff1aSopenharmony_ci 461cabdff1aSopenharmony_ci ret = decode_inter_block(s, gb, quant_matrix, &skip, &map); 462cabdff1aSopenharmony_ci if (ret < 0) 463cabdff1aSopenharmony_ci return ret; 464cabdff1aSopenharmony_ci 465cabdff1aSopenharmony_ci if (orig_mv_x >= -32) { 466cabdff1aSopenharmony_ci if (y * 8 + mv_y < 0 || y * 8 + mv_y + 8 > h || 467cabdff1aSopenharmony_ci x * 8 + mv_x < 0 || x * 8 + mv_x + 8 > w) 468cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 469cabdff1aSopenharmony_ci 470cabdff1aSopenharmony_ci copy_block8(frame->data[plane] + (s->blocks_h - 1 - y) * 8 * frame->linesize[plane] + x * 8, 471cabdff1aSopenharmony_ci prev->data[plane] + ((s->blocks_h - 1 - y) * 8 - mv_y) * prev->linesize[plane] + (x * 8 + mv_x), 472cabdff1aSopenharmony_ci frame->linesize[plane], prev->linesize[plane], 8); 473cabdff1aSopenharmony_ci if (map) { 474cabdff1aSopenharmony_ci s->idsp.idct(s->block); 475cabdff1aSopenharmony_ci for (int i = 0; i < 64; i++) 476cabdff1aSopenharmony_ci s->block[i] = (s->block[i] + 1) & 0xFFFC; 477cabdff1aSopenharmony_ci s->idsp.add_pixels_clamped(s->block, frame->data[plane] + (s->blocks_h - 1 - y) * 8 * frame->linesize[plane] + x * 8, 478cabdff1aSopenharmony_ci frame->linesize[plane]); 479cabdff1aSopenharmony_ci } 480cabdff1aSopenharmony_ci } else if (map) { 481cabdff1aSopenharmony_ci s->idsp.idct_put(frame->data[plane] + (s->blocks_h - 1 - y) * 8 * frame->linesize[plane] + x * 8, 482cabdff1aSopenharmony_ci frame->linesize[plane], s->block); 483cabdff1aSopenharmony_ci } 484cabdff1aSopenharmony_ci } 485cabdff1aSopenharmony_ci } 486cabdff1aSopenharmony_ci } else if (s->flags & 1) { 487cabdff1aSopenharmony_ci av_fast_padded_malloc(&s->wblocks, &s->wblocks_size, 488cabdff1aSopenharmony_ci 64 * s->blocks_w * sizeof(*s->wblocks)); 489cabdff1aSopenharmony_ci if (!s->wblocks) 490cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 491cabdff1aSopenharmony_ci 492cabdff1aSopenharmony_ci av_fast_padded_malloc(&s->map, &s->map_size, 493cabdff1aSopenharmony_ci s->blocks_w * sizeof(*s->map)); 494cabdff1aSopenharmony_ci if (!s->map) 495cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 496cabdff1aSopenharmony_ci 497cabdff1aSopenharmony_ci for (int y = 0; y < s->blocks_h; y++) { 498cabdff1aSopenharmony_ci ret = decode_inter_blocks(s, gb, quant_matrix, &skip, s->map); 499cabdff1aSopenharmony_ci if (ret < 0) 500cabdff1aSopenharmony_ci return ret; 501cabdff1aSopenharmony_ci 502cabdff1aSopenharmony_ci for (int x = 0; x < s->blocks_w; x++) { 503cabdff1aSopenharmony_ci if (!s->map[x]) 504cabdff1aSopenharmony_ci continue; 505cabdff1aSopenharmony_ci s->idsp.idct_add(frame->data[plane] + (s->blocks_h - 1 - y) * 8 * frame->linesize[plane] + x * 8, 506cabdff1aSopenharmony_ci frame->linesize[plane], s->wblocks + 64 * x); 507cabdff1aSopenharmony_ci } 508cabdff1aSopenharmony_ci } 509cabdff1aSopenharmony_ci } else { 510cabdff1aSopenharmony_ci for (int y = 0; y < s->blocks_h; y++) { 511cabdff1aSopenharmony_ci for (int x = 0; x < s->blocks_w; x++) { 512cabdff1aSopenharmony_ci int map = 0; 513cabdff1aSopenharmony_ci 514cabdff1aSopenharmony_ci ret = decode_inter_block(s, gb, quant_matrix, &skip, &map); 515cabdff1aSopenharmony_ci if (ret < 0) 516cabdff1aSopenharmony_ci return ret; 517cabdff1aSopenharmony_ci 518cabdff1aSopenharmony_ci if (!map) 519cabdff1aSopenharmony_ci continue; 520cabdff1aSopenharmony_ci s->idsp.idct_add(frame->data[plane] + (s->blocks_h - 1 - y) * 8 * frame->linesize[plane] + x * 8, 521cabdff1aSopenharmony_ci frame->linesize[plane], s->block); 522cabdff1aSopenharmony_ci } 523cabdff1aSopenharmony_ci } 524cabdff1aSopenharmony_ci } 525cabdff1aSopenharmony_ci 526cabdff1aSopenharmony_ci align_get_bits(gb); 527cabdff1aSopenharmony_ci if (get_bits_left(gb) < 0) 528cabdff1aSopenharmony_ci av_log(s->avctx, AV_LOG_WARNING, "overread\n"); 529cabdff1aSopenharmony_ci if (get_bits_left(gb) > 0) 530cabdff1aSopenharmony_ci av_log(s->avctx, AV_LOG_WARNING, "underread: %d\n", get_bits_left(gb)); 531cabdff1aSopenharmony_ci 532cabdff1aSopenharmony_ci return 0; 533cabdff1aSopenharmony_ci} 534cabdff1aSopenharmony_ci 535cabdff1aSopenharmony_cistatic void compute_quant_matrix(AGMContext *s, double qscale) 536cabdff1aSopenharmony_ci{ 537cabdff1aSopenharmony_ci int luma[64], chroma[64]; 538cabdff1aSopenharmony_ci double f = 1.0 - fabs(qscale); 539cabdff1aSopenharmony_ci 540cabdff1aSopenharmony_ci if (!s->key_frame && (s->flags & 2)) { 541cabdff1aSopenharmony_ci if (qscale >= 0.0) { 542cabdff1aSopenharmony_ci for (int i = 0; i < 64; i++) { 543cabdff1aSopenharmony_ci luma[i] = FFMAX(1, 16 * f); 544cabdff1aSopenharmony_ci chroma[i] = FFMAX(1, 16 * f); 545cabdff1aSopenharmony_ci } 546cabdff1aSopenharmony_ci } else { 547cabdff1aSopenharmony_ci for (int i = 0; i < 64; i++) { 548cabdff1aSopenharmony_ci luma[i] = FFMAX(1, 16 - qscale * 32); 549cabdff1aSopenharmony_ci chroma[i] = FFMAX(1, 16 - qscale * 32); 550cabdff1aSopenharmony_ci } 551cabdff1aSopenharmony_ci } 552cabdff1aSopenharmony_ci } else { 553cabdff1aSopenharmony_ci if (qscale >= 0.0) { 554cabdff1aSopenharmony_ci for (int i = 0; i < 64; i++) { 555cabdff1aSopenharmony_ci luma[i] = FFMAX(1, unscaled_luma [(i & 7) * 8 + (i >> 3)] * f); 556cabdff1aSopenharmony_ci chroma[i] = FFMAX(1, unscaled_chroma[(i & 7) * 8 + (i >> 3)] * f); 557cabdff1aSopenharmony_ci } 558cabdff1aSopenharmony_ci } else { 559cabdff1aSopenharmony_ci for (int i = 0; i < 64; i++) { 560cabdff1aSopenharmony_ci luma[i] = FFMAX(1, 255.0 - (255 - unscaled_luma [(i & 7) * 8 + (i >> 3)]) * f); 561cabdff1aSopenharmony_ci chroma[i] = FFMAX(1, 255.0 - (255 - unscaled_chroma[(i & 7) * 8 + (i >> 3)]) * f); 562cabdff1aSopenharmony_ci } 563cabdff1aSopenharmony_ci } 564cabdff1aSopenharmony_ci } 565cabdff1aSopenharmony_ci 566cabdff1aSopenharmony_ci for (int i = 0; i < 64; i++) { 567cabdff1aSopenharmony_ci int pos = ff_zigzag_direct[i]; 568cabdff1aSopenharmony_ci 569cabdff1aSopenharmony_ci s->luma_quant_matrix[i] = luma[pos] * ((pos / 8) & 1 ? -1 : 1); 570cabdff1aSopenharmony_ci s->chroma_quant_matrix[i] = chroma[pos] * ((pos / 8) & 1 ? -1 : 1); 571cabdff1aSopenharmony_ci } 572cabdff1aSopenharmony_ci} 573cabdff1aSopenharmony_ci 574cabdff1aSopenharmony_cistatic int decode_raw_intra_rgb(AVCodecContext *avctx, GetByteContext *gbyte, AVFrame *frame) 575cabdff1aSopenharmony_ci{ 576cabdff1aSopenharmony_ci uint8_t *dst = frame->data[0] + (avctx->height - 1) * frame->linesize[0]; 577cabdff1aSopenharmony_ci uint8_t r = 0, g = 0, b = 0; 578cabdff1aSopenharmony_ci 579cabdff1aSopenharmony_ci if (bytestream2_get_bytes_left(gbyte) < 3 * avctx->width * avctx->height) 580cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 581cabdff1aSopenharmony_ci 582cabdff1aSopenharmony_ci for (int y = 0; y < avctx->height; y++) { 583cabdff1aSopenharmony_ci for (int x = 0; x < avctx->width; x++) { 584cabdff1aSopenharmony_ci dst[x*3+0] = bytestream2_get_byteu(gbyte) + r; 585cabdff1aSopenharmony_ci r = dst[x*3+0]; 586cabdff1aSopenharmony_ci dst[x*3+1] = bytestream2_get_byteu(gbyte) + g; 587cabdff1aSopenharmony_ci g = dst[x*3+1]; 588cabdff1aSopenharmony_ci dst[x*3+2] = bytestream2_get_byteu(gbyte) + b; 589cabdff1aSopenharmony_ci b = dst[x*3+2]; 590cabdff1aSopenharmony_ci } 591cabdff1aSopenharmony_ci dst -= frame->linesize[0]; 592cabdff1aSopenharmony_ci } 593cabdff1aSopenharmony_ci 594cabdff1aSopenharmony_ci return 0; 595cabdff1aSopenharmony_ci} 596cabdff1aSopenharmony_ci 597cabdff1aSopenharmony_ciav_always_inline static int fill_pixels(uint8_t **y0, uint8_t **y1, 598cabdff1aSopenharmony_ci uint8_t **u, uint8_t **v, 599cabdff1aSopenharmony_ci int ylinesize, int ulinesize, int vlinesize, 600cabdff1aSopenharmony_ci uint8_t *fill, 601cabdff1aSopenharmony_ci int *nx, int *ny, int *np, int w, int h) 602cabdff1aSopenharmony_ci{ 603cabdff1aSopenharmony_ci uint8_t *y0dst = *y0; 604cabdff1aSopenharmony_ci uint8_t *y1dst = *y1; 605cabdff1aSopenharmony_ci uint8_t *udst = *u; 606cabdff1aSopenharmony_ci uint8_t *vdst = *v; 607cabdff1aSopenharmony_ci int x = *nx, y = *ny, pos = *np; 608cabdff1aSopenharmony_ci 609cabdff1aSopenharmony_ci if (pos == 0) { 610cabdff1aSopenharmony_ci y0dst[2*x+0] += fill[0]; 611cabdff1aSopenharmony_ci y0dst[2*x+1] += fill[1]; 612cabdff1aSopenharmony_ci y1dst[2*x+0] += fill[2]; 613cabdff1aSopenharmony_ci y1dst[2*x+1] += fill[3]; 614cabdff1aSopenharmony_ci pos++; 615cabdff1aSopenharmony_ci } else if (pos == 1) { 616cabdff1aSopenharmony_ci udst[x] += fill[0]; 617cabdff1aSopenharmony_ci vdst[x] += fill[1]; 618cabdff1aSopenharmony_ci x++; 619cabdff1aSopenharmony_ci if (x >= w) { 620cabdff1aSopenharmony_ci x = 0; 621cabdff1aSopenharmony_ci y++; 622cabdff1aSopenharmony_ci if (y >= h) 623cabdff1aSopenharmony_ci return 1; 624cabdff1aSopenharmony_ci y0dst -= 2*ylinesize; 625cabdff1aSopenharmony_ci y1dst -= 2*ylinesize; 626cabdff1aSopenharmony_ci udst -= ulinesize; 627cabdff1aSopenharmony_ci vdst -= vlinesize; 628cabdff1aSopenharmony_ci } 629cabdff1aSopenharmony_ci y0dst[2*x+0] += fill[2]; 630cabdff1aSopenharmony_ci y0dst[2*x+1] += fill[3]; 631cabdff1aSopenharmony_ci pos++; 632cabdff1aSopenharmony_ci } else if (pos == 2) { 633cabdff1aSopenharmony_ci y1dst[2*x+0] += fill[0]; 634cabdff1aSopenharmony_ci y1dst[2*x+1] += fill[1]; 635cabdff1aSopenharmony_ci udst[x] += fill[2]; 636cabdff1aSopenharmony_ci vdst[x] += fill[3]; 637cabdff1aSopenharmony_ci x++; 638cabdff1aSopenharmony_ci if (x >= w) { 639cabdff1aSopenharmony_ci x = 0; 640cabdff1aSopenharmony_ci y++; 641cabdff1aSopenharmony_ci if (y >= h) 642cabdff1aSopenharmony_ci return 1; 643cabdff1aSopenharmony_ci y0dst -= 2*ylinesize; 644cabdff1aSopenharmony_ci y1dst -= 2*ylinesize; 645cabdff1aSopenharmony_ci udst -= ulinesize; 646cabdff1aSopenharmony_ci vdst -= vlinesize; 647cabdff1aSopenharmony_ci } 648cabdff1aSopenharmony_ci pos = 0; 649cabdff1aSopenharmony_ci } 650cabdff1aSopenharmony_ci 651cabdff1aSopenharmony_ci *y0 = y0dst; 652cabdff1aSopenharmony_ci *y1 = y1dst; 653cabdff1aSopenharmony_ci *u = udst; 654cabdff1aSopenharmony_ci *v = vdst; 655cabdff1aSopenharmony_ci *np = pos; 656cabdff1aSopenharmony_ci *nx = x; 657cabdff1aSopenharmony_ci *ny = y; 658cabdff1aSopenharmony_ci 659cabdff1aSopenharmony_ci return 0; 660cabdff1aSopenharmony_ci} 661cabdff1aSopenharmony_ci 662cabdff1aSopenharmony_cistatic int decode_runlen_rgb(AVCodecContext *avctx, GetByteContext *gbyte, AVFrame *frame) 663cabdff1aSopenharmony_ci{ 664cabdff1aSopenharmony_ci uint8_t *dst = frame->data[0] + (avctx->height - 1) * frame->linesize[0]; 665cabdff1aSopenharmony_ci int runlen, y = 0, x = 0; 666cabdff1aSopenharmony_ci uint8_t fill[4]; 667cabdff1aSopenharmony_ci unsigned code; 668cabdff1aSopenharmony_ci 669cabdff1aSopenharmony_ci while (bytestream2_get_bytes_left(gbyte) > 0) { 670cabdff1aSopenharmony_ci code = bytestream2_peek_le32(gbyte); 671cabdff1aSopenharmony_ci runlen = code & 0xFFFFFF; 672cabdff1aSopenharmony_ci 673cabdff1aSopenharmony_ci if (code >> 24 == 0x77) { 674cabdff1aSopenharmony_ci bytestream2_skip(gbyte, 4); 675cabdff1aSopenharmony_ci 676cabdff1aSopenharmony_ci for (int i = 0; i < 4; i++) 677cabdff1aSopenharmony_ci fill[i] = bytestream2_get_byte(gbyte); 678cabdff1aSopenharmony_ci 679cabdff1aSopenharmony_ci while (runlen > 0) { 680cabdff1aSopenharmony_ci runlen--; 681cabdff1aSopenharmony_ci 682cabdff1aSopenharmony_ci for (int i = 0; i < 4; i++) { 683cabdff1aSopenharmony_ci dst[x] += fill[i]; 684cabdff1aSopenharmony_ci x++; 685cabdff1aSopenharmony_ci if (x >= frame->width * 3) { 686cabdff1aSopenharmony_ci x = 0; 687cabdff1aSopenharmony_ci y++; 688cabdff1aSopenharmony_ci dst -= frame->linesize[0]; 689cabdff1aSopenharmony_ci if (y >= frame->height) 690cabdff1aSopenharmony_ci return 0; 691cabdff1aSopenharmony_ci } 692cabdff1aSopenharmony_ci } 693cabdff1aSopenharmony_ci } 694cabdff1aSopenharmony_ci } else { 695cabdff1aSopenharmony_ci for (int i = 0; i < 4; i++) 696cabdff1aSopenharmony_ci fill[i] = bytestream2_get_byte(gbyte); 697cabdff1aSopenharmony_ci 698cabdff1aSopenharmony_ci for (int i = 0; i < 4; i++) { 699cabdff1aSopenharmony_ci dst[x] += fill[i]; 700cabdff1aSopenharmony_ci x++; 701cabdff1aSopenharmony_ci if (x >= frame->width * 3) { 702cabdff1aSopenharmony_ci x = 0; 703cabdff1aSopenharmony_ci y++; 704cabdff1aSopenharmony_ci dst -= frame->linesize[0]; 705cabdff1aSopenharmony_ci if (y >= frame->height) 706cabdff1aSopenharmony_ci return 0; 707cabdff1aSopenharmony_ci } 708cabdff1aSopenharmony_ci } 709cabdff1aSopenharmony_ci } 710cabdff1aSopenharmony_ci } 711cabdff1aSopenharmony_ci 712cabdff1aSopenharmony_ci return 0; 713cabdff1aSopenharmony_ci} 714cabdff1aSopenharmony_ci 715cabdff1aSopenharmony_cistatic int decode_runlen(AVCodecContext *avctx, GetByteContext *gbyte, AVFrame *frame) 716cabdff1aSopenharmony_ci{ 717cabdff1aSopenharmony_ci uint8_t *y0dst = frame->data[0] + (avctx->height - 1) * frame->linesize[0]; 718cabdff1aSopenharmony_ci uint8_t *y1dst = y0dst - frame->linesize[0]; 719cabdff1aSopenharmony_ci uint8_t *udst = frame->data[1] + ((avctx->height >> 1) - 1) * frame->linesize[1]; 720cabdff1aSopenharmony_ci uint8_t *vdst = frame->data[2] + ((avctx->height >> 1) - 1) * frame->linesize[2]; 721cabdff1aSopenharmony_ci int runlen, y = 0, x = 0, pos = 0; 722cabdff1aSopenharmony_ci uint8_t fill[4]; 723cabdff1aSopenharmony_ci unsigned code; 724cabdff1aSopenharmony_ci 725cabdff1aSopenharmony_ci while (bytestream2_get_bytes_left(gbyte) > 0) { 726cabdff1aSopenharmony_ci code = bytestream2_peek_le32(gbyte); 727cabdff1aSopenharmony_ci runlen = code & 0xFFFFFF; 728cabdff1aSopenharmony_ci 729cabdff1aSopenharmony_ci if (code >> 24 == 0x77) { 730cabdff1aSopenharmony_ci bytestream2_skip(gbyte, 4); 731cabdff1aSopenharmony_ci 732cabdff1aSopenharmony_ci for (int i = 0; i < 4; i++) 733cabdff1aSopenharmony_ci fill[i] = bytestream2_get_byte(gbyte); 734cabdff1aSopenharmony_ci 735cabdff1aSopenharmony_ci while (runlen > 0) { 736cabdff1aSopenharmony_ci runlen--; 737cabdff1aSopenharmony_ci 738cabdff1aSopenharmony_ci if (fill_pixels(&y0dst, &y1dst, &udst, &vdst, 739cabdff1aSopenharmony_ci frame->linesize[0], 740cabdff1aSopenharmony_ci frame->linesize[1], 741cabdff1aSopenharmony_ci frame->linesize[2], 742cabdff1aSopenharmony_ci fill, &x, &y, &pos, 743cabdff1aSopenharmony_ci avctx->width / 2, 744cabdff1aSopenharmony_ci avctx->height / 2)) 745cabdff1aSopenharmony_ci return 0; 746cabdff1aSopenharmony_ci } 747cabdff1aSopenharmony_ci } else { 748cabdff1aSopenharmony_ci for (int i = 0; i < 4; i++) 749cabdff1aSopenharmony_ci fill[i] = bytestream2_get_byte(gbyte); 750cabdff1aSopenharmony_ci 751cabdff1aSopenharmony_ci if (fill_pixels(&y0dst, &y1dst, &udst, &vdst, 752cabdff1aSopenharmony_ci frame->linesize[0], 753cabdff1aSopenharmony_ci frame->linesize[1], 754cabdff1aSopenharmony_ci frame->linesize[2], 755cabdff1aSopenharmony_ci fill, &x, &y, &pos, 756cabdff1aSopenharmony_ci avctx->width / 2, 757cabdff1aSopenharmony_ci avctx->height / 2)) 758cabdff1aSopenharmony_ci return 0; 759cabdff1aSopenharmony_ci } 760cabdff1aSopenharmony_ci } 761cabdff1aSopenharmony_ci 762cabdff1aSopenharmony_ci return 0; 763cabdff1aSopenharmony_ci} 764cabdff1aSopenharmony_ci 765cabdff1aSopenharmony_cistatic int decode_raw_intra(AVCodecContext *avctx, GetByteContext *gbyte, AVFrame *frame) 766cabdff1aSopenharmony_ci{ 767cabdff1aSopenharmony_ci uint8_t *y0dst = frame->data[0] + (avctx->height - 1) * frame->linesize[0]; 768cabdff1aSopenharmony_ci uint8_t *y1dst = y0dst - frame->linesize[0]; 769cabdff1aSopenharmony_ci uint8_t *udst = frame->data[1] + ((avctx->height >> 1) - 1) * frame->linesize[1]; 770cabdff1aSopenharmony_ci uint8_t *vdst = frame->data[2] + ((avctx->height >> 1) - 1) * frame->linesize[2]; 771cabdff1aSopenharmony_ci uint8_t ly0 = 0, ly1 = 0, ly2 = 0, ly3 = 0, lu = 0, lv = 0; 772cabdff1aSopenharmony_ci 773cabdff1aSopenharmony_ci for (int y = 0; y < avctx->height / 2; y++) { 774cabdff1aSopenharmony_ci for (int x = 0; x < avctx->width / 2; x++) { 775cabdff1aSopenharmony_ci y0dst[x*2+0] = bytestream2_get_byte(gbyte) + ly0; 776cabdff1aSopenharmony_ci ly0 = y0dst[x*2+0]; 777cabdff1aSopenharmony_ci y0dst[x*2+1] = bytestream2_get_byte(gbyte) + ly1; 778cabdff1aSopenharmony_ci ly1 = y0dst[x*2+1]; 779cabdff1aSopenharmony_ci y1dst[x*2+0] = bytestream2_get_byte(gbyte) + ly2; 780cabdff1aSopenharmony_ci ly2 = y1dst[x*2+0]; 781cabdff1aSopenharmony_ci y1dst[x*2+1] = bytestream2_get_byte(gbyte) + ly3; 782cabdff1aSopenharmony_ci ly3 = y1dst[x*2+1]; 783cabdff1aSopenharmony_ci udst[x] = bytestream2_get_byte(gbyte) + lu; 784cabdff1aSopenharmony_ci lu = udst[x]; 785cabdff1aSopenharmony_ci vdst[x] = bytestream2_get_byte(gbyte) + lv; 786cabdff1aSopenharmony_ci lv = vdst[x]; 787cabdff1aSopenharmony_ci } 788cabdff1aSopenharmony_ci 789cabdff1aSopenharmony_ci y0dst -= 2*frame->linesize[0]; 790cabdff1aSopenharmony_ci y1dst -= 2*frame->linesize[0]; 791cabdff1aSopenharmony_ci udst -= frame->linesize[1]; 792cabdff1aSopenharmony_ci vdst -= frame->linesize[2]; 793cabdff1aSopenharmony_ci } 794cabdff1aSopenharmony_ci 795cabdff1aSopenharmony_ci return 0; 796cabdff1aSopenharmony_ci} 797cabdff1aSopenharmony_ci 798cabdff1aSopenharmony_cistatic int decode_intra(AVCodecContext *avctx, GetBitContext *gb, AVFrame *frame) 799cabdff1aSopenharmony_ci{ 800cabdff1aSopenharmony_ci AGMContext *s = avctx->priv_data; 801cabdff1aSopenharmony_ci int ret; 802cabdff1aSopenharmony_ci 803cabdff1aSopenharmony_ci compute_quant_matrix(s, (2 * s->compression - 100) / 100.0); 804cabdff1aSopenharmony_ci 805cabdff1aSopenharmony_ci s->blocks_w = avctx->coded_width >> 3; 806cabdff1aSopenharmony_ci s->blocks_h = avctx->coded_height >> 3; 807cabdff1aSopenharmony_ci 808cabdff1aSopenharmony_ci ret = decode_intra_plane(s, gb, s->size[0], s->luma_quant_matrix, frame, 0); 809cabdff1aSopenharmony_ci if (ret < 0) 810cabdff1aSopenharmony_ci return ret; 811cabdff1aSopenharmony_ci 812cabdff1aSopenharmony_ci bytestream2_skip(&s->gbyte, s->size[0]); 813cabdff1aSopenharmony_ci 814cabdff1aSopenharmony_ci s->blocks_w = avctx->coded_width >> 4; 815cabdff1aSopenharmony_ci s->blocks_h = avctx->coded_height >> 4; 816cabdff1aSopenharmony_ci 817cabdff1aSopenharmony_ci ret = decode_intra_plane(s, gb, s->size[1], s->chroma_quant_matrix, frame, 2); 818cabdff1aSopenharmony_ci if (ret < 0) 819cabdff1aSopenharmony_ci return ret; 820cabdff1aSopenharmony_ci 821cabdff1aSopenharmony_ci bytestream2_skip(&s->gbyte, s->size[1]); 822cabdff1aSopenharmony_ci 823cabdff1aSopenharmony_ci s->blocks_w = avctx->coded_width >> 4; 824cabdff1aSopenharmony_ci s->blocks_h = avctx->coded_height >> 4; 825cabdff1aSopenharmony_ci 826cabdff1aSopenharmony_ci ret = decode_intra_plane(s, gb, s->size[2], s->chroma_quant_matrix, frame, 1); 827cabdff1aSopenharmony_ci if (ret < 0) 828cabdff1aSopenharmony_ci return ret; 829cabdff1aSopenharmony_ci 830cabdff1aSopenharmony_ci return 0; 831cabdff1aSopenharmony_ci} 832cabdff1aSopenharmony_ci 833cabdff1aSopenharmony_cistatic int decode_motion_vectors(AVCodecContext *avctx, GetBitContext *gb) 834cabdff1aSopenharmony_ci{ 835cabdff1aSopenharmony_ci AGMContext *s = avctx->priv_data; 836cabdff1aSopenharmony_ci int nb_mvs = ((avctx->coded_height + 15) >> 4) * ((avctx->coded_width + 15) >> 4); 837cabdff1aSopenharmony_ci int ret, skip = 0, value, map; 838cabdff1aSopenharmony_ci 839cabdff1aSopenharmony_ci av_fast_padded_malloc(&s->mvectors, &s->mvectors_size, 840cabdff1aSopenharmony_ci nb_mvs * sizeof(*s->mvectors)); 841cabdff1aSopenharmony_ci if (!s->mvectors) 842cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 843cabdff1aSopenharmony_ci 844cabdff1aSopenharmony_ci if ((ret = init_get_bits8(gb, s->gbyte.buffer, bytestream2_get_bytes_left(&s->gbyte) - 845cabdff1aSopenharmony_ci (s->size[0] + s->size[1] + s->size[2]))) < 0) 846cabdff1aSopenharmony_ci return ret; 847cabdff1aSopenharmony_ci 848cabdff1aSopenharmony_ci memset(s->mvectors, 0, sizeof(*s->mvectors) * nb_mvs); 849cabdff1aSopenharmony_ci 850cabdff1aSopenharmony_ci for (int i = 0; i < nb_mvs; i++) { 851cabdff1aSopenharmony_ci ret = read_code(gb, &skip, &value, &map, 1); 852cabdff1aSopenharmony_ci if (ret < 0) 853cabdff1aSopenharmony_ci return ret; 854cabdff1aSopenharmony_ci s->mvectors[i].x = value; 855cabdff1aSopenharmony_ci i += skip; 856cabdff1aSopenharmony_ci } 857cabdff1aSopenharmony_ci 858cabdff1aSopenharmony_ci for (int i = 0; i < nb_mvs; i++) { 859cabdff1aSopenharmony_ci ret = read_code(gb, &skip, &value, &map, 1); 860cabdff1aSopenharmony_ci if (ret < 0) 861cabdff1aSopenharmony_ci return ret; 862cabdff1aSopenharmony_ci s->mvectors[i].y = value; 863cabdff1aSopenharmony_ci i += skip; 864cabdff1aSopenharmony_ci } 865cabdff1aSopenharmony_ci 866cabdff1aSopenharmony_ci if (get_bits_left(gb) <= 0) 867cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 868cabdff1aSopenharmony_ci skip = (get_bits_count(gb) >> 3) + 1; 869cabdff1aSopenharmony_ci bytestream2_skip(&s->gbyte, skip); 870cabdff1aSopenharmony_ci 871cabdff1aSopenharmony_ci return 0; 872cabdff1aSopenharmony_ci} 873cabdff1aSopenharmony_ci 874cabdff1aSopenharmony_cistatic int decode_inter(AVCodecContext *avctx, GetBitContext *gb, 875cabdff1aSopenharmony_ci AVFrame *frame, AVFrame *prev) 876cabdff1aSopenharmony_ci{ 877cabdff1aSopenharmony_ci AGMContext *s = avctx->priv_data; 878cabdff1aSopenharmony_ci int ret; 879cabdff1aSopenharmony_ci 880cabdff1aSopenharmony_ci compute_quant_matrix(s, (2 * s->compression - 100) / 100.0); 881cabdff1aSopenharmony_ci 882cabdff1aSopenharmony_ci if (s->flags & 2) { 883cabdff1aSopenharmony_ci ret = decode_motion_vectors(avctx, gb); 884cabdff1aSopenharmony_ci if (ret < 0) 885cabdff1aSopenharmony_ci return ret; 886cabdff1aSopenharmony_ci } 887cabdff1aSopenharmony_ci 888cabdff1aSopenharmony_ci s->blocks_w = avctx->coded_width >> 3; 889cabdff1aSopenharmony_ci s->blocks_h = avctx->coded_height >> 3; 890cabdff1aSopenharmony_ci 891cabdff1aSopenharmony_ci ret = decode_inter_plane(s, gb, s->size[0], s->luma_quant_matrix, frame, prev, 0); 892cabdff1aSopenharmony_ci if (ret < 0) 893cabdff1aSopenharmony_ci return ret; 894cabdff1aSopenharmony_ci 895cabdff1aSopenharmony_ci bytestream2_skip(&s->gbyte, s->size[0]); 896cabdff1aSopenharmony_ci 897cabdff1aSopenharmony_ci s->blocks_w = avctx->coded_width >> 4; 898cabdff1aSopenharmony_ci s->blocks_h = avctx->coded_height >> 4; 899cabdff1aSopenharmony_ci 900cabdff1aSopenharmony_ci ret = decode_inter_plane(s, gb, s->size[1], s->chroma_quant_matrix, frame, prev, 2); 901cabdff1aSopenharmony_ci if (ret < 0) 902cabdff1aSopenharmony_ci return ret; 903cabdff1aSopenharmony_ci 904cabdff1aSopenharmony_ci bytestream2_skip(&s->gbyte, s->size[1]); 905cabdff1aSopenharmony_ci 906cabdff1aSopenharmony_ci s->blocks_w = avctx->coded_width >> 4; 907cabdff1aSopenharmony_ci s->blocks_h = avctx->coded_height >> 4; 908cabdff1aSopenharmony_ci 909cabdff1aSopenharmony_ci ret = decode_inter_plane(s, gb, s->size[2], s->chroma_quant_matrix, frame, prev, 1); 910cabdff1aSopenharmony_ci if (ret < 0) 911cabdff1aSopenharmony_ci return ret; 912cabdff1aSopenharmony_ci 913cabdff1aSopenharmony_ci return 0; 914cabdff1aSopenharmony_ci} 915cabdff1aSopenharmony_ci 916cabdff1aSopenharmony_citypedef struct Node { 917cabdff1aSopenharmony_ci int parent; 918cabdff1aSopenharmony_ci int child[2]; 919cabdff1aSopenharmony_ci} Node; 920cabdff1aSopenharmony_ci 921cabdff1aSopenharmony_cistatic void get_tree_codes(uint32_t *codes, Node *nodes, int idx, uint32_t pfx, int bitpos) 922cabdff1aSopenharmony_ci{ 923cabdff1aSopenharmony_ci if (idx < 256 && idx >= 0) { 924cabdff1aSopenharmony_ci codes[idx] = pfx; 925cabdff1aSopenharmony_ci } else if (idx >= 0) { 926cabdff1aSopenharmony_ci get_tree_codes(codes, nodes, nodes[idx].child[0], pfx + (0 << bitpos), bitpos + 1); 927cabdff1aSopenharmony_ci get_tree_codes(codes, nodes, nodes[idx].child[1], pfx + (1U << bitpos), bitpos + 1); 928cabdff1aSopenharmony_ci } 929cabdff1aSopenharmony_ci} 930cabdff1aSopenharmony_ci 931cabdff1aSopenharmony_cistatic int make_new_tree(const uint8_t *bitlens, uint32_t *codes) 932cabdff1aSopenharmony_ci{ 933cabdff1aSopenharmony_ci int zlcount = 0, curlen, idx, nindex, last, llast; 934cabdff1aSopenharmony_ci int blcounts[32] = { 0 }; 935cabdff1aSopenharmony_ci int syms[8192]; 936cabdff1aSopenharmony_ci Node nodes[512]; 937cabdff1aSopenharmony_ci int node_idx[1024]; 938cabdff1aSopenharmony_ci int old_idx[512]; 939cabdff1aSopenharmony_ci 940cabdff1aSopenharmony_ci for (int i = 0; i < 256; i++) { 941cabdff1aSopenharmony_ci int bitlen = bitlens[i]; 942cabdff1aSopenharmony_ci int blcount = blcounts[bitlen]; 943cabdff1aSopenharmony_ci 944cabdff1aSopenharmony_ci zlcount += bitlen < 1; 945cabdff1aSopenharmony_ci syms[(bitlen << 8) + blcount] = i; 946cabdff1aSopenharmony_ci blcounts[bitlen]++; 947cabdff1aSopenharmony_ci } 948cabdff1aSopenharmony_ci 949cabdff1aSopenharmony_ci for (int i = 0; i < 512; i++) { 950cabdff1aSopenharmony_ci nodes[i].child[0] = -1; 951cabdff1aSopenharmony_ci nodes[i].child[1] = -1; 952cabdff1aSopenharmony_ci } 953cabdff1aSopenharmony_ci 954cabdff1aSopenharmony_ci for (int i = 0; i < 256; i++) { 955cabdff1aSopenharmony_ci node_idx[i] = 257 + i; 956cabdff1aSopenharmony_ci } 957cabdff1aSopenharmony_ci 958cabdff1aSopenharmony_ci curlen = 1; 959cabdff1aSopenharmony_ci node_idx[512] = 256; 960cabdff1aSopenharmony_ci last = 255; 961cabdff1aSopenharmony_ci nindex = 1; 962cabdff1aSopenharmony_ci 963cabdff1aSopenharmony_ci for (curlen = 1; curlen < 32; curlen++) { 964cabdff1aSopenharmony_ci if (blcounts[curlen] > 0) { 965cabdff1aSopenharmony_ci int max_zlcount = zlcount + blcounts[curlen]; 966cabdff1aSopenharmony_ci 967cabdff1aSopenharmony_ci for (int i = 0; zlcount < 256 && zlcount < max_zlcount; zlcount++, i++) { 968cabdff1aSopenharmony_ci int p = node_idx[nindex - 1 + 512]; 969cabdff1aSopenharmony_ci int ch = syms[256 * curlen + i]; 970cabdff1aSopenharmony_ci 971cabdff1aSopenharmony_ci if (nindex <= 0) 972cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 973cabdff1aSopenharmony_ci 974cabdff1aSopenharmony_ci if (nodes[p].child[0] == -1) { 975cabdff1aSopenharmony_ci nodes[p].child[0] = ch; 976cabdff1aSopenharmony_ci } else { 977cabdff1aSopenharmony_ci nodes[p].child[1] = ch; 978cabdff1aSopenharmony_ci nindex--; 979cabdff1aSopenharmony_ci } 980cabdff1aSopenharmony_ci nodes[ch].parent = p; 981cabdff1aSopenharmony_ci } 982cabdff1aSopenharmony_ci } 983cabdff1aSopenharmony_ci llast = last - 1; 984cabdff1aSopenharmony_ci idx = 0; 985cabdff1aSopenharmony_ci while (nindex > 0) { 986cabdff1aSopenharmony_ci int p, ch; 987cabdff1aSopenharmony_ci 988cabdff1aSopenharmony_ci last = llast - idx; 989cabdff1aSopenharmony_ci p = node_idx[nindex - 1 + 512]; 990cabdff1aSopenharmony_ci ch = node_idx[last]; 991cabdff1aSopenharmony_ci if (nodes[p].child[0] == -1) { 992cabdff1aSopenharmony_ci nodes[p].child[0] = ch; 993cabdff1aSopenharmony_ci } else { 994cabdff1aSopenharmony_ci nodes[p].child[1] = ch; 995cabdff1aSopenharmony_ci nindex--; 996cabdff1aSopenharmony_ci } 997cabdff1aSopenharmony_ci old_idx[idx] = ch; 998cabdff1aSopenharmony_ci nodes[ch].parent = p; 999cabdff1aSopenharmony_ci if (idx == llast) 1000cabdff1aSopenharmony_ci goto next; 1001cabdff1aSopenharmony_ci idx++; 1002cabdff1aSopenharmony_ci if (nindex <= 0) { 1003cabdff1aSopenharmony_ci for (int i = 0; i < idx; i++) 1004cabdff1aSopenharmony_ci node_idx[512 + i] = old_idx[i]; 1005cabdff1aSopenharmony_ci } 1006cabdff1aSopenharmony_ci } 1007cabdff1aSopenharmony_ci nindex = idx; 1008cabdff1aSopenharmony_ci } 1009cabdff1aSopenharmony_ci 1010cabdff1aSopenharmony_cinext: 1011cabdff1aSopenharmony_ci 1012cabdff1aSopenharmony_ci get_tree_codes(codes, nodes, 256, 0, 0); 1013cabdff1aSopenharmony_ci return 0; 1014cabdff1aSopenharmony_ci} 1015cabdff1aSopenharmony_ci 1016cabdff1aSopenharmony_cistatic int build_huff(const uint8_t *bitlen, VLC *vlc) 1017cabdff1aSopenharmony_ci{ 1018cabdff1aSopenharmony_ci uint32_t new_codes[256]; 1019cabdff1aSopenharmony_ci uint8_t bits[256]; 1020cabdff1aSopenharmony_ci uint8_t symbols[256]; 1021cabdff1aSopenharmony_ci uint32_t codes[256]; 1022cabdff1aSopenharmony_ci int nb_codes = 0; 1023cabdff1aSopenharmony_ci 1024cabdff1aSopenharmony_ci int ret = make_new_tree(bitlen, new_codes); 1025cabdff1aSopenharmony_ci if (ret < 0) 1026cabdff1aSopenharmony_ci return ret; 1027cabdff1aSopenharmony_ci 1028cabdff1aSopenharmony_ci for (int i = 0; i < 256; i++) { 1029cabdff1aSopenharmony_ci if (bitlen[i]) { 1030cabdff1aSopenharmony_ci bits[nb_codes] = bitlen[i]; 1031cabdff1aSopenharmony_ci codes[nb_codes] = new_codes[i]; 1032cabdff1aSopenharmony_ci symbols[nb_codes] = i; 1033cabdff1aSopenharmony_ci nb_codes++; 1034cabdff1aSopenharmony_ci } 1035cabdff1aSopenharmony_ci } 1036cabdff1aSopenharmony_ci 1037cabdff1aSopenharmony_ci ff_free_vlc(vlc); 1038cabdff1aSopenharmony_ci return ff_init_vlc_sparse(vlc, 13, nb_codes, 1039cabdff1aSopenharmony_ci bits, 1, 1, 1040cabdff1aSopenharmony_ci codes, 4, 4, 1041cabdff1aSopenharmony_ci symbols, 1, 1, 1042cabdff1aSopenharmony_ci INIT_VLC_LE); 1043cabdff1aSopenharmony_ci} 1044cabdff1aSopenharmony_ci 1045cabdff1aSopenharmony_cistatic int decode_huffman2(AVCodecContext *avctx, int header, int size) 1046cabdff1aSopenharmony_ci{ 1047cabdff1aSopenharmony_ci AGMContext *s = avctx->priv_data; 1048cabdff1aSopenharmony_ci GetBitContext *gb = &s->gb; 1049cabdff1aSopenharmony_ci uint8_t lens[256]; 1050cabdff1aSopenharmony_ci int ret, x, len; 1051cabdff1aSopenharmony_ci 1052cabdff1aSopenharmony_ci if ((ret = init_get_bits8(gb, s->gbyte.buffer, 1053cabdff1aSopenharmony_ci bytestream2_get_bytes_left(&s->gbyte))) < 0) 1054cabdff1aSopenharmony_ci return ret; 1055cabdff1aSopenharmony_ci 1056cabdff1aSopenharmony_ci s->output_size = get_bits_long(gb, 32); 1057cabdff1aSopenharmony_ci 1058cabdff1aSopenharmony_ci if (s->output_size > avctx->width * avctx->height * 9LL + 10000) 1059cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 1060cabdff1aSopenharmony_ci 1061cabdff1aSopenharmony_ci av_fast_padded_malloc(&s->output, &s->padded_output_size, s->output_size); 1062cabdff1aSopenharmony_ci if (!s->output) 1063cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 1064cabdff1aSopenharmony_ci 1065cabdff1aSopenharmony_ci x = get_bits(gb, 1); 1066cabdff1aSopenharmony_ci len = 4 + get_bits(gb, 1); 1067cabdff1aSopenharmony_ci if (x) { 1068cabdff1aSopenharmony_ci int cb[8] = { 0 }; 1069cabdff1aSopenharmony_ci int count = get_bits(gb, 3) + 1; 1070cabdff1aSopenharmony_ci 1071cabdff1aSopenharmony_ci for (int i = 0; i < count; i++) 1072cabdff1aSopenharmony_ci cb[i] = get_bits(gb, len); 1073cabdff1aSopenharmony_ci 1074cabdff1aSopenharmony_ci for (int i = 0; i < 256; i++) { 1075cabdff1aSopenharmony_ci int idx = get_bits(gb, 3); 1076cabdff1aSopenharmony_ci lens[i] = cb[idx]; 1077cabdff1aSopenharmony_ci } 1078cabdff1aSopenharmony_ci } else { 1079cabdff1aSopenharmony_ci for (int i = 0; i < 256; i++) 1080cabdff1aSopenharmony_ci lens[i] = get_bits(gb, len); 1081cabdff1aSopenharmony_ci } 1082cabdff1aSopenharmony_ci 1083cabdff1aSopenharmony_ci if ((ret = build_huff(lens, &s->vlc)) < 0) 1084cabdff1aSopenharmony_ci return ret; 1085cabdff1aSopenharmony_ci 1086cabdff1aSopenharmony_ci x = 0; 1087cabdff1aSopenharmony_ci while (get_bits_left(gb) > 0 && x < s->output_size) { 1088cabdff1aSopenharmony_ci int val = get_vlc2(gb, s->vlc.table, s->vlc.bits, 3); 1089cabdff1aSopenharmony_ci if (val < 0) 1090cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 1091cabdff1aSopenharmony_ci s->output[x++] = val; 1092cabdff1aSopenharmony_ci } 1093cabdff1aSopenharmony_ci 1094cabdff1aSopenharmony_ci return 0; 1095cabdff1aSopenharmony_ci} 1096cabdff1aSopenharmony_ci 1097cabdff1aSopenharmony_cistatic int decode_frame(AVCodecContext *avctx, AVFrame *frame, 1098cabdff1aSopenharmony_ci int *got_frame, AVPacket *avpkt) 1099cabdff1aSopenharmony_ci{ 1100cabdff1aSopenharmony_ci AGMContext *s = avctx->priv_data; 1101cabdff1aSopenharmony_ci GetBitContext *gb = &s->gb; 1102cabdff1aSopenharmony_ci GetByteContext *gbyte = &s->gbyte; 1103cabdff1aSopenharmony_ci int w, h, width, height, header; 1104cabdff1aSopenharmony_ci unsigned compressed_size; 1105cabdff1aSopenharmony_ci long skip; 1106cabdff1aSopenharmony_ci int ret; 1107cabdff1aSopenharmony_ci 1108cabdff1aSopenharmony_ci if (!avpkt->size) 1109cabdff1aSopenharmony_ci return 0; 1110cabdff1aSopenharmony_ci 1111cabdff1aSopenharmony_ci bytestream2_init(gbyte, avpkt->data, avpkt->size); 1112cabdff1aSopenharmony_ci 1113cabdff1aSopenharmony_ci header = bytestream2_get_le32(gbyte); 1114cabdff1aSopenharmony_ci s->fflags = bytestream2_get_le32(gbyte); 1115cabdff1aSopenharmony_ci s->bitstream_size = s->fflags & 0x1FFFFFFF; 1116cabdff1aSopenharmony_ci s->fflags >>= 29; 1117cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_DEBUG, "fflags: %X\n", s->fflags); 1118cabdff1aSopenharmony_ci if (avpkt->size < s->bitstream_size + 8) 1119cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 1120cabdff1aSopenharmony_ci 1121cabdff1aSopenharmony_ci s->key_frame = (avpkt->flags & AV_PKT_FLAG_KEY); 1122cabdff1aSopenharmony_ci frame->key_frame = s->key_frame; 1123cabdff1aSopenharmony_ci frame->pict_type = s->key_frame ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P; 1124cabdff1aSopenharmony_ci 1125cabdff1aSopenharmony_ci if (!s->key_frame) { 1126cabdff1aSopenharmony_ci if (!s->prev_frame->data[0]) { 1127cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "Missing reference frame.\n"); 1128cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 1129cabdff1aSopenharmony_ci } 1130cabdff1aSopenharmony_ci } 1131cabdff1aSopenharmony_ci 1132cabdff1aSopenharmony_ci if (header) { 1133cabdff1aSopenharmony_ci if (avctx->codec_tag == MKTAG('A', 'G', 'M', '0') || 1134cabdff1aSopenharmony_ci avctx->codec_tag == MKTAG('A', 'G', 'M', '1')) 1135cabdff1aSopenharmony_ci return AVERROR_PATCHWELCOME; 1136cabdff1aSopenharmony_ci else 1137cabdff1aSopenharmony_ci ret = decode_huffman2(avctx, header, (avpkt->size - s->bitstream_size) - 8); 1138cabdff1aSopenharmony_ci if (ret < 0) 1139cabdff1aSopenharmony_ci return ret; 1140cabdff1aSopenharmony_ci bytestream2_init(gbyte, s->output, s->output_size); 1141cabdff1aSopenharmony_ci } else if (!s->dct) { 1142cabdff1aSopenharmony_ci bytestream2_skip(gbyte, 4); 1143cabdff1aSopenharmony_ci } 1144cabdff1aSopenharmony_ci 1145cabdff1aSopenharmony_ci if (s->dct) { 1146cabdff1aSopenharmony_ci s->flags = 0; 1147cabdff1aSopenharmony_ci w = bytestream2_get_le32(gbyte); 1148cabdff1aSopenharmony_ci h = bytestream2_get_le32(gbyte); 1149cabdff1aSopenharmony_ci if (w == INT32_MIN || h == INT32_MIN) 1150cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 1151cabdff1aSopenharmony_ci if (w < 0) { 1152cabdff1aSopenharmony_ci w = -w; 1153cabdff1aSopenharmony_ci s->flags |= 2; 1154cabdff1aSopenharmony_ci } 1155cabdff1aSopenharmony_ci if (h < 0) { 1156cabdff1aSopenharmony_ci h = -h; 1157cabdff1aSopenharmony_ci s->flags |= 1; 1158cabdff1aSopenharmony_ci } 1159cabdff1aSopenharmony_ci 1160cabdff1aSopenharmony_ci width = avctx->width; 1161cabdff1aSopenharmony_ci height = avctx->height; 1162cabdff1aSopenharmony_ci if (w < width || h < height || w & 7 || h & 7) 1163cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 1164cabdff1aSopenharmony_ci 1165cabdff1aSopenharmony_ci ret = ff_set_dimensions(avctx, w, h); 1166cabdff1aSopenharmony_ci if (ret < 0) 1167cabdff1aSopenharmony_ci return ret; 1168cabdff1aSopenharmony_ci avctx->width = width; 1169cabdff1aSopenharmony_ci avctx->height = height; 1170cabdff1aSopenharmony_ci 1171cabdff1aSopenharmony_ci s->compression = bytestream2_get_le32(gbyte); 1172cabdff1aSopenharmony_ci if (s->compression < 0 || s->compression > 100) 1173cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 1174cabdff1aSopenharmony_ci 1175cabdff1aSopenharmony_ci for (int i = 0; i < 3; i++) 1176cabdff1aSopenharmony_ci s->size[i] = bytestream2_get_le32(gbyte); 1177cabdff1aSopenharmony_ci if (header) { 1178cabdff1aSopenharmony_ci compressed_size = s->output_size; 1179cabdff1aSopenharmony_ci skip = 8LL; 1180cabdff1aSopenharmony_ci } else { 1181cabdff1aSopenharmony_ci compressed_size = avpkt->size; 1182cabdff1aSopenharmony_ci skip = 32LL; 1183cabdff1aSopenharmony_ci } 1184cabdff1aSopenharmony_ci if (s->size[0] < 0 || s->size[1] < 0 || s->size[2] < 0 || 1185cabdff1aSopenharmony_ci skip + s->size[0] + s->size[1] + s->size[2] > compressed_size) { 1186cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 1187cabdff1aSopenharmony_ci } 1188cabdff1aSopenharmony_ci } 1189cabdff1aSopenharmony_ci 1190cabdff1aSopenharmony_ci if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0) 1191cabdff1aSopenharmony_ci return ret; 1192cabdff1aSopenharmony_ci 1193cabdff1aSopenharmony_ci if (frame->key_frame) { 1194cabdff1aSopenharmony_ci if (!s->dct && !s->rgb) 1195cabdff1aSopenharmony_ci ret = decode_raw_intra(avctx, gbyte, frame); 1196cabdff1aSopenharmony_ci else if (!s->dct && s->rgb) 1197cabdff1aSopenharmony_ci ret = decode_raw_intra_rgb(avctx, gbyte, frame); 1198cabdff1aSopenharmony_ci else 1199cabdff1aSopenharmony_ci ret = decode_intra(avctx, gb, frame); 1200cabdff1aSopenharmony_ci } else { 1201cabdff1aSopenharmony_ci if (s->prev_frame-> width != frame->width || 1202cabdff1aSopenharmony_ci s->prev_frame->height != frame->height) 1203cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 1204cabdff1aSopenharmony_ci 1205cabdff1aSopenharmony_ci if (!(s->flags & 2)) { 1206cabdff1aSopenharmony_ci ret = av_frame_copy(frame, s->prev_frame); 1207cabdff1aSopenharmony_ci if (ret < 0) 1208cabdff1aSopenharmony_ci return ret; 1209cabdff1aSopenharmony_ci } 1210cabdff1aSopenharmony_ci 1211cabdff1aSopenharmony_ci if (s->dct) { 1212cabdff1aSopenharmony_ci ret = decode_inter(avctx, gb, frame, s->prev_frame); 1213cabdff1aSopenharmony_ci } else if (!s->dct && !s->rgb) { 1214cabdff1aSopenharmony_ci ret = decode_runlen(avctx, gbyte, frame); 1215cabdff1aSopenharmony_ci } else { 1216cabdff1aSopenharmony_ci ret = decode_runlen_rgb(avctx, gbyte, frame); 1217cabdff1aSopenharmony_ci } 1218cabdff1aSopenharmony_ci } 1219cabdff1aSopenharmony_ci if (ret < 0) 1220cabdff1aSopenharmony_ci return ret; 1221cabdff1aSopenharmony_ci 1222cabdff1aSopenharmony_ci av_frame_unref(s->prev_frame); 1223cabdff1aSopenharmony_ci if ((ret = av_frame_ref(s->prev_frame, frame)) < 0) 1224cabdff1aSopenharmony_ci return ret; 1225cabdff1aSopenharmony_ci 1226cabdff1aSopenharmony_ci frame->crop_top = avctx->coded_height - avctx->height; 1227cabdff1aSopenharmony_ci frame->crop_left = avctx->coded_width - avctx->width; 1228cabdff1aSopenharmony_ci 1229cabdff1aSopenharmony_ci *got_frame = 1; 1230cabdff1aSopenharmony_ci 1231cabdff1aSopenharmony_ci return avpkt->size; 1232cabdff1aSopenharmony_ci} 1233cabdff1aSopenharmony_ci 1234cabdff1aSopenharmony_cistatic av_cold int decode_init(AVCodecContext *avctx) 1235cabdff1aSopenharmony_ci{ 1236cabdff1aSopenharmony_ci AGMContext *s = avctx->priv_data; 1237cabdff1aSopenharmony_ci 1238cabdff1aSopenharmony_ci s->rgb = avctx->codec_tag == MKTAG('A', 'G', 'M', '4'); 1239cabdff1aSopenharmony_ci avctx->pix_fmt = s->rgb ? AV_PIX_FMT_BGR24 : AV_PIX_FMT_YUV420P; 1240cabdff1aSopenharmony_ci s->avctx = avctx; 1241cabdff1aSopenharmony_ci s->plus = avctx->codec_tag == MKTAG('A', 'G', 'M', '3') || 1242cabdff1aSopenharmony_ci avctx->codec_tag == MKTAG('A', 'G', 'M', '7'); 1243cabdff1aSopenharmony_ci 1244cabdff1aSopenharmony_ci s->dct = avctx->codec_tag != MKTAG('A', 'G', 'M', '4') && 1245cabdff1aSopenharmony_ci avctx->codec_tag != MKTAG('A', 'G', 'M', '5'); 1246cabdff1aSopenharmony_ci 1247cabdff1aSopenharmony_ci if (!s->rgb && !s->dct) { 1248cabdff1aSopenharmony_ci if ((avctx->width & 1) || (avctx->height & 1)) 1249cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 1250cabdff1aSopenharmony_ci } 1251cabdff1aSopenharmony_ci 1252cabdff1aSopenharmony_ci avctx->idct_algo = FF_IDCT_SIMPLE; 1253cabdff1aSopenharmony_ci ff_idctdsp_init(&s->idsp, avctx); 1254cabdff1aSopenharmony_ci ff_init_scantable(s->idsp.idct_permutation, &s->scantable, ff_zigzag_direct); 1255cabdff1aSopenharmony_ci 1256cabdff1aSopenharmony_ci s->prev_frame = av_frame_alloc(); 1257cabdff1aSopenharmony_ci if (!s->prev_frame) 1258cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 1259cabdff1aSopenharmony_ci 1260cabdff1aSopenharmony_ci return 0; 1261cabdff1aSopenharmony_ci} 1262cabdff1aSopenharmony_ci 1263cabdff1aSopenharmony_cistatic void decode_flush(AVCodecContext *avctx) 1264cabdff1aSopenharmony_ci{ 1265cabdff1aSopenharmony_ci AGMContext *s = avctx->priv_data; 1266cabdff1aSopenharmony_ci 1267cabdff1aSopenharmony_ci av_frame_unref(s->prev_frame); 1268cabdff1aSopenharmony_ci} 1269cabdff1aSopenharmony_ci 1270cabdff1aSopenharmony_cistatic av_cold int decode_close(AVCodecContext *avctx) 1271cabdff1aSopenharmony_ci{ 1272cabdff1aSopenharmony_ci AGMContext *s = avctx->priv_data; 1273cabdff1aSopenharmony_ci 1274cabdff1aSopenharmony_ci ff_free_vlc(&s->vlc); 1275cabdff1aSopenharmony_ci av_frame_free(&s->prev_frame); 1276cabdff1aSopenharmony_ci av_freep(&s->mvectors); 1277cabdff1aSopenharmony_ci s->mvectors_size = 0; 1278cabdff1aSopenharmony_ci av_freep(&s->wblocks); 1279cabdff1aSopenharmony_ci s->wblocks_size = 0; 1280cabdff1aSopenharmony_ci av_freep(&s->output); 1281cabdff1aSopenharmony_ci s->padded_output_size = 0; 1282cabdff1aSopenharmony_ci av_freep(&s->map); 1283cabdff1aSopenharmony_ci s->map_size = 0; 1284cabdff1aSopenharmony_ci 1285cabdff1aSopenharmony_ci return 0; 1286cabdff1aSopenharmony_ci} 1287cabdff1aSopenharmony_ci 1288cabdff1aSopenharmony_ciconst FFCodec ff_agm_decoder = { 1289cabdff1aSopenharmony_ci .p.name = "agm", 1290cabdff1aSopenharmony_ci .p.long_name = NULL_IF_CONFIG_SMALL("Amuse Graphics Movie"), 1291cabdff1aSopenharmony_ci .p.type = AVMEDIA_TYPE_VIDEO, 1292cabdff1aSopenharmony_ci .p.id = AV_CODEC_ID_AGM, 1293cabdff1aSopenharmony_ci .p.capabilities = AV_CODEC_CAP_DR1, 1294cabdff1aSopenharmony_ci .priv_data_size = sizeof(AGMContext), 1295cabdff1aSopenharmony_ci .init = decode_init, 1296cabdff1aSopenharmony_ci .close = decode_close, 1297cabdff1aSopenharmony_ci FF_CODEC_DECODE_CB(decode_frame), 1298cabdff1aSopenharmony_ci .flush = decode_flush, 1299cabdff1aSopenharmony_ci .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | 1300cabdff1aSopenharmony_ci FF_CODEC_CAP_INIT_CLEANUP | 1301cabdff1aSopenharmony_ci FF_CODEC_CAP_EXPORTS_CROPPING, 1302cabdff1aSopenharmony_ci}; 1303