1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * YUY2 Lossless Codec 3cabdff1aSopenharmony_ci * 4cabdff1aSopenharmony_ci * This file is part of FFmpeg. 5cabdff1aSopenharmony_ci * 6cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 7cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 8cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 9cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 10cabdff1aSopenharmony_ci * 11cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 12cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 13cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14cabdff1aSopenharmony_ci * Lesser General Public License for more details. 15cabdff1aSopenharmony_ci * 16cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 17cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software 18cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19cabdff1aSopenharmony_ci */ 20cabdff1aSopenharmony_ci 21cabdff1aSopenharmony_ci#include <stdio.h> 22cabdff1aSopenharmony_ci#include <stdlib.h> 23cabdff1aSopenharmony_ci#include <string.h> 24cabdff1aSopenharmony_ci 25cabdff1aSopenharmony_ci#define YLC_VLC_BITS 10 26cabdff1aSopenharmony_ci 27cabdff1aSopenharmony_ci#include "libavutil/imgutils.h" 28cabdff1aSopenharmony_ci#include "libavutil/internal.h" 29cabdff1aSopenharmony_ci#include "libavutil/intreadwrite.h" 30cabdff1aSopenharmony_ci#include "libavutil/mem.h" 31cabdff1aSopenharmony_ci#include "avcodec.h" 32cabdff1aSopenharmony_ci#include "bswapdsp.h" 33cabdff1aSopenharmony_ci#include "codec_internal.h" 34cabdff1aSopenharmony_ci#include "get_bits.h" 35cabdff1aSopenharmony_ci#include "huffyuvdsp.h" 36cabdff1aSopenharmony_ci#include "thread.h" 37cabdff1aSopenharmony_ci#include "unary.h" 38cabdff1aSopenharmony_ci 39cabdff1aSopenharmony_citypedef struct YLCContext { 40cabdff1aSopenharmony_ci VLC vlc[4]; 41cabdff1aSopenharmony_ci uint32_t table[256]; 42cabdff1aSopenharmony_ci uint8_t *buffer; 43cabdff1aSopenharmony_ci int buffer_size; 44cabdff1aSopenharmony_ci BswapDSPContext bdsp; 45cabdff1aSopenharmony_ci} YLCContext; 46cabdff1aSopenharmony_ci 47cabdff1aSopenharmony_cistatic av_cold int decode_init(AVCodecContext *avctx) 48cabdff1aSopenharmony_ci{ 49cabdff1aSopenharmony_ci YLCContext *s = avctx->priv_data; 50cabdff1aSopenharmony_ci 51cabdff1aSopenharmony_ci avctx->pix_fmt = AV_PIX_FMT_YUYV422; 52cabdff1aSopenharmony_ci ff_bswapdsp_init(&s->bdsp); 53cabdff1aSopenharmony_ci 54cabdff1aSopenharmony_ci return 0; 55cabdff1aSopenharmony_ci} 56cabdff1aSopenharmony_ci 57cabdff1aSopenharmony_citypedef struct Node { 58cabdff1aSopenharmony_ci int16_t sym; 59cabdff1aSopenharmony_ci uint32_t count; 60cabdff1aSopenharmony_ci int16_t l, r; 61cabdff1aSopenharmony_ci} Node; 62cabdff1aSopenharmony_ci 63cabdff1aSopenharmony_cistatic void get_tree_codes(uint32_t *bits, int16_t *lens, uint8_t *xlat, 64cabdff1aSopenharmony_ci Node *nodes, int node, 65cabdff1aSopenharmony_ci uint32_t pfx, int pl, int *pos) 66cabdff1aSopenharmony_ci{ 67cabdff1aSopenharmony_ci int s; 68cabdff1aSopenharmony_ci 69cabdff1aSopenharmony_ci s = nodes[node].sym; 70cabdff1aSopenharmony_ci if (s != -1) { 71cabdff1aSopenharmony_ci bits[*pos] = (~pfx) & ((1ULL << FFMAX(pl, 1)) - 1); 72cabdff1aSopenharmony_ci lens[*pos] = FFMAX(pl, 1); 73cabdff1aSopenharmony_ci xlat[*pos] = s + (pl == 0); 74cabdff1aSopenharmony_ci (*pos)++; 75cabdff1aSopenharmony_ci } else { 76cabdff1aSopenharmony_ci pfx <<= 1; 77cabdff1aSopenharmony_ci pl++; 78cabdff1aSopenharmony_ci get_tree_codes(bits, lens, xlat, nodes, nodes[node].l, pfx, pl, 79cabdff1aSopenharmony_ci pos); 80cabdff1aSopenharmony_ci pfx |= 1; 81cabdff1aSopenharmony_ci get_tree_codes(bits, lens, xlat, nodes, nodes[node].r, pfx, pl, 82cabdff1aSopenharmony_ci pos); 83cabdff1aSopenharmony_ci } 84cabdff1aSopenharmony_ci} 85cabdff1aSopenharmony_ci 86cabdff1aSopenharmony_cistatic int build_vlc(AVCodecContext *avctx, VLC *vlc, const uint32_t *table) 87cabdff1aSopenharmony_ci{ 88cabdff1aSopenharmony_ci Node nodes[512]; 89cabdff1aSopenharmony_ci uint32_t bits[256]; 90cabdff1aSopenharmony_ci int16_t lens[256]; 91cabdff1aSopenharmony_ci uint8_t xlat[256]; 92cabdff1aSopenharmony_ci int cur_node, i, j, pos = 0; 93cabdff1aSopenharmony_ci 94cabdff1aSopenharmony_ci ff_free_vlc(vlc); 95cabdff1aSopenharmony_ci 96cabdff1aSopenharmony_ci for (i = 0; i < 256; i++) { 97cabdff1aSopenharmony_ci nodes[i].count = table[i]; 98cabdff1aSopenharmony_ci nodes[i].sym = i; 99cabdff1aSopenharmony_ci nodes[i].l = i; 100cabdff1aSopenharmony_ci nodes[i].r = i; 101cabdff1aSopenharmony_ci } 102cabdff1aSopenharmony_ci 103cabdff1aSopenharmony_ci cur_node = 256; 104cabdff1aSopenharmony_ci j = 0; 105cabdff1aSopenharmony_ci do { 106cabdff1aSopenharmony_ci for (i = 0; ; i++) { 107cabdff1aSopenharmony_ci int new_node = j; 108cabdff1aSopenharmony_ci int first_node = cur_node; 109cabdff1aSopenharmony_ci int second_node = cur_node; 110cabdff1aSopenharmony_ci unsigned nd, st; 111cabdff1aSopenharmony_ci 112cabdff1aSopenharmony_ci nodes[cur_node].count = -1; 113cabdff1aSopenharmony_ci 114cabdff1aSopenharmony_ci do { 115cabdff1aSopenharmony_ci int val = nodes[new_node].count; 116cabdff1aSopenharmony_ci if (val && (val < nodes[first_node].count)) { 117cabdff1aSopenharmony_ci if (val >= nodes[second_node].count) { 118cabdff1aSopenharmony_ci first_node = new_node; 119cabdff1aSopenharmony_ci } else { 120cabdff1aSopenharmony_ci first_node = second_node; 121cabdff1aSopenharmony_ci second_node = new_node; 122cabdff1aSopenharmony_ci } 123cabdff1aSopenharmony_ci } 124cabdff1aSopenharmony_ci new_node += 1; 125cabdff1aSopenharmony_ci } while (new_node != cur_node); 126cabdff1aSopenharmony_ci 127cabdff1aSopenharmony_ci if (first_node == cur_node) 128cabdff1aSopenharmony_ci break; 129cabdff1aSopenharmony_ci 130cabdff1aSopenharmony_ci nd = nodes[second_node].count; 131cabdff1aSopenharmony_ci st = nodes[first_node].count; 132cabdff1aSopenharmony_ci nodes[second_node].count = 0; 133cabdff1aSopenharmony_ci nodes[first_node].count = 0; 134cabdff1aSopenharmony_ci if (nd >= UINT32_MAX - st) { 135cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "count overflow\n"); 136cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 137cabdff1aSopenharmony_ci } 138cabdff1aSopenharmony_ci nodes[cur_node].count = nd + st; 139cabdff1aSopenharmony_ci nodes[cur_node].sym = -1; 140cabdff1aSopenharmony_ci nodes[cur_node].l = first_node; 141cabdff1aSopenharmony_ci nodes[cur_node].r = second_node; 142cabdff1aSopenharmony_ci cur_node++; 143cabdff1aSopenharmony_ci } 144cabdff1aSopenharmony_ci j++; 145cabdff1aSopenharmony_ci } while (cur_node - 256 == j); 146cabdff1aSopenharmony_ci 147cabdff1aSopenharmony_ci get_tree_codes(bits, lens, xlat, nodes, cur_node - 1, 0, 0, &pos); 148cabdff1aSopenharmony_ci 149cabdff1aSopenharmony_ci return ff_init_vlc_sparse(vlc, YLC_VLC_BITS, pos, lens, 2, 2, 150cabdff1aSopenharmony_ci bits, 4, 4, xlat, 1, 1, 0); 151cabdff1aSopenharmony_ci} 152cabdff1aSopenharmony_ci 153cabdff1aSopenharmony_cistatic const uint8_t table_y1[] = { 154cabdff1aSopenharmony_ci 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 155cabdff1aSopenharmony_ci 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 156cabdff1aSopenharmony_ci 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 157cabdff1aSopenharmony_ci 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 158cabdff1aSopenharmony_ci 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 159cabdff1aSopenharmony_ci 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 160cabdff1aSopenharmony_ci 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 161cabdff1aSopenharmony_ci 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 162cabdff1aSopenharmony_ci 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 163cabdff1aSopenharmony_ci 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 164cabdff1aSopenharmony_ci 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 165cabdff1aSopenharmony_ci 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 166cabdff1aSopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 167cabdff1aSopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 168cabdff1aSopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 169cabdff1aSopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 170cabdff1aSopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 171cabdff1aSopenharmony_ci 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 172cabdff1aSopenharmony_ci 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 173cabdff1aSopenharmony_ci 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 174cabdff1aSopenharmony_ci 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 175cabdff1aSopenharmony_ci 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 176cabdff1aSopenharmony_ci 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 177cabdff1aSopenharmony_ci 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 178cabdff1aSopenharmony_ci 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 179cabdff1aSopenharmony_ci 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 180cabdff1aSopenharmony_ci 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 181cabdff1aSopenharmony_ci 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 182cabdff1aSopenharmony_ci 0x02, 0x00, 183cabdff1aSopenharmony_ci}; 184cabdff1aSopenharmony_ci 185cabdff1aSopenharmony_cistatic const uint8_t table_u[] = { 186cabdff1aSopenharmony_ci 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 187cabdff1aSopenharmony_ci 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 188cabdff1aSopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 189cabdff1aSopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 190cabdff1aSopenharmony_ci 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 191cabdff1aSopenharmony_ci 0x01, 0x01, 0x01, 0x01, 0x01, 0xFF, 0xFF, 0xFF, 192cabdff1aSopenharmony_ci 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 193cabdff1aSopenharmony_ci 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 194cabdff1aSopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 195cabdff1aSopenharmony_ci 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 196cabdff1aSopenharmony_ci 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 197cabdff1aSopenharmony_ci 0x01, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 198cabdff1aSopenharmony_ci 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 199cabdff1aSopenharmony_ci 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 200cabdff1aSopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 201cabdff1aSopenharmony_ci 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 202cabdff1aSopenharmony_ci 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0xFF, 203cabdff1aSopenharmony_ci 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 204cabdff1aSopenharmony_ci 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 205cabdff1aSopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 206cabdff1aSopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 207cabdff1aSopenharmony_ci 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 208cabdff1aSopenharmony_ci 0x01, 0x01, 0x01, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 209cabdff1aSopenharmony_ci 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 210cabdff1aSopenharmony_ci 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 211cabdff1aSopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 212cabdff1aSopenharmony_ci 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 213cabdff1aSopenharmony_ci 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 214cabdff1aSopenharmony_ci 0x01, 0x00, 215cabdff1aSopenharmony_ci}; 216cabdff1aSopenharmony_ci 217cabdff1aSopenharmony_cistatic const uint8_t table_y2[] = { 218cabdff1aSopenharmony_ci 0xFC, 0xFC, 0xFC, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE, 219cabdff1aSopenharmony_ci 0xFE, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFC, 220cabdff1aSopenharmony_ci 0xFC, 0xFC, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE, 0xFE, 221cabdff1aSopenharmony_ci 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFC, 0xFC, 222cabdff1aSopenharmony_ci 0xFC, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE, 0xFE, 0xFF, 223cabdff1aSopenharmony_ci 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFD, 0xFD, 0xFD, 224cabdff1aSopenharmony_ci 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 225cabdff1aSopenharmony_ci 0x00, 0x01, 0x01, 0x01, 0xFD, 0xFD, 0xFD, 0xFE, 226cabdff1aSopenharmony_ci 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 227cabdff1aSopenharmony_ci 0x01, 0x01, 0x01, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE, 228cabdff1aSopenharmony_ci 0xFE, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 229cabdff1aSopenharmony_ci 0x01, 0x01, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 230cabdff1aSopenharmony_ci 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 231cabdff1aSopenharmony_ci 0x02, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0x00, 232cabdff1aSopenharmony_ci 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 233cabdff1aSopenharmony_ci 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 234cabdff1aSopenharmony_ci 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0xFF, 235cabdff1aSopenharmony_ci 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 236cabdff1aSopenharmony_ci 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0xFF, 0xFF, 237cabdff1aSopenharmony_ci 0xFF, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 238cabdff1aSopenharmony_ci 0x02, 0x02, 0x03, 0x03, 0x03, 0xFF, 0xFF, 0xFF, 239cabdff1aSopenharmony_ci 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 240cabdff1aSopenharmony_ci 0x02, 0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x01, 241cabdff1aSopenharmony_ci 0x01, 0x01, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 242cabdff1aSopenharmony_ci 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x01, 0x01, 243cabdff1aSopenharmony_ci 0x01, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x04, 244cabdff1aSopenharmony_ci 0x04, 0x04, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 245cabdff1aSopenharmony_ci 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x04, 0x04, 246cabdff1aSopenharmony_ci 0x04, 0x00, 247cabdff1aSopenharmony_ci}; 248cabdff1aSopenharmony_ci 249cabdff1aSopenharmony_cistatic const uint8_t table_v[] = { 250cabdff1aSopenharmony_ci 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 251cabdff1aSopenharmony_ci 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 252cabdff1aSopenharmony_ci 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 253cabdff1aSopenharmony_ci 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 254cabdff1aSopenharmony_ci 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 255cabdff1aSopenharmony_ci 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 256cabdff1aSopenharmony_ci 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 257cabdff1aSopenharmony_ci 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 258cabdff1aSopenharmony_ci 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 259cabdff1aSopenharmony_ci 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 260cabdff1aSopenharmony_ci 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 261cabdff1aSopenharmony_ci 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 262cabdff1aSopenharmony_ci 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 263cabdff1aSopenharmony_ci 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 264cabdff1aSopenharmony_ci 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 265cabdff1aSopenharmony_ci 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 266cabdff1aSopenharmony_ci 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 267cabdff1aSopenharmony_ci 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 268cabdff1aSopenharmony_ci 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 269cabdff1aSopenharmony_ci 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 270cabdff1aSopenharmony_ci 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 271cabdff1aSopenharmony_ci 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 272cabdff1aSopenharmony_ci 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 273cabdff1aSopenharmony_ci 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 274cabdff1aSopenharmony_ci 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 275cabdff1aSopenharmony_ci 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 276cabdff1aSopenharmony_ci 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 277cabdff1aSopenharmony_ci 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 278cabdff1aSopenharmony_ci 0x01, 0x00, 279cabdff1aSopenharmony_ci}; 280cabdff1aSopenharmony_ci 281cabdff1aSopenharmony_cistatic int decode_frame(AVCodecContext *avctx, AVFrame *p, 282cabdff1aSopenharmony_ci int *got_frame, AVPacket *avpkt) 283cabdff1aSopenharmony_ci{ 284cabdff1aSopenharmony_ci int TL[4] = { 128, 128, 128, 128 }; 285cabdff1aSopenharmony_ci int L[4] = { 128, 128, 128, 128 }; 286cabdff1aSopenharmony_ci YLCContext *s = avctx->priv_data; 287cabdff1aSopenharmony_ci const uint8_t *buf = avpkt->data; 288cabdff1aSopenharmony_ci int ret, x, y, toffset, boffset; 289cabdff1aSopenharmony_ci GetBitContext gb; 290cabdff1aSopenharmony_ci uint8_t *dst; 291cabdff1aSopenharmony_ci 292cabdff1aSopenharmony_ci if (avpkt->size <= 16) 293cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 294cabdff1aSopenharmony_ci 295cabdff1aSopenharmony_ci if (AV_RL32(buf) != MKTAG('Y', 'L', 'C', '0') || 296cabdff1aSopenharmony_ci AV_RL32(buf + 4) != 0) 297cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 298cabdff1aSopenharmony_ci 299cabdff1aSopenharmony_ci toffset = AV_RL32(buf + 8); 300cabdff1aSopenharmony_ci if (toffset < 16 || toffset >= avpkt->size) 301cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 302cabdff1aSopenharmony_ci 303cabdff1aSopenharmony_ci boffset = AV_RL32(buf + 12); 304cabdff1aSopenharmony_ci if (toffset >= boffset || boffset >= avpkt->size) 305cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 306cabdff1aSopenharmony_ci 307cabdff1aSopenharmony_ci if ((ret = ff_thread_get_buffer(avctx, p, 0)) < 0) 308cabdff1aSopenharmony_ci return ret; 309cabdff1aSopenharmony_ci 310cabdff1aSopenharmony_ci av_fast_malloc(&s->buffer, &s->buffer_size, 311cabdff1aSopenharmony_ci FFMAX(boffset - toffset, avpkt->size - boffset) 312cabdff1aSopenharmony_ci + AV_INPUT_BUFFER_PADDING_SIZE); 313cabdff1aSopenharmony_ci if (!s->buffer) 314cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 315cabdff1aSopenharmony_ci 316cabdff1aSopenharmony_ci memcpy(s->buffer, avpkt->data + toffset, boffset - toffset); 317cabdff1aSopenharmony_ci memset(s->buffer + boffset - toffset, 0, AV_INPUT_BUFFER_PADDING_SIZE); 318cabdff1aSopenharmony_ci s->bdsp.bswap_buf((uint32_t *) s->buffer, 319cabdff1aSopenharmony_ci (uint32_t *) s->buffer, 320cabdff1aSopenharmony_ci (boffset - toffset + 3) >> 2); 321cabdff1aSopenharmony_ci if ((ret = init_get_bits8(&gb, s->buffer, boffset - toffset)) < 0) 322cabdff1aSopenharmony_ci return ret; 323cabdff1aSopenharmony_ci 324cabdff1aSopenharmony_ci for (int i = 0; i < 4; i++) { 325cabdff1aSopenharmony_ci for (x = 0; x < 256; x++) { 326cabdff1aSopenharmony_ci unsigned len = get_unary(&gb, 1, 31); 327cabdff1aSopenharmony_ci uint32_t val = ((1U << len) - 1) + get_bits_long(&gb, len); 328cabdff1aSopenharmony_ci 329cabdff1aSopenharmony_ci s->table[x] = val; 330cabdff1aSopenharmony_ci } 331cabdff1aSopenharmony_ci 332cabdff1aSopenharmony_ci ret = build_vlc(avctx, &s->vlc[i], s->table); 333cabdff1aSopenharmony_ci if (ret < 0) 334cabdff1aSopenharmony_ci return ret; 335cabdff1aSopenharmony_ci } 336cabdff1aSopenharmony_ci 337cabdff1aSopenharmony_ci memcpy(s->buffer, avpkt->data + boffset, avpkt->size - boffset); 338cabdff1aSopenharmony_ci memset(s->buffer + avpkt->size - boffset, 0, AV_INPUT_BUFFER_PADDING_SIZE); 339cabdff1aSopenharmony_ci s->bdsp.bswap_buf((uint32_t *) s->buffer, 340cabdff1aSopenharmony_ci (uint32_t *) s->buffer, 341cabdff1aSopenharmony_ci (avpkt->size - boffset) >> 2); 342cabdff1aSopenharmony_ci if ((ret = init_get_bits8(&gb, s->buffer, avpkt->size - boffset)) < 0) 343cabdff1aSopenharmony_ci return ret; 344cabdff1aSopenharmony_ci 345cabdff1aSopenharmony_ci dst = p->data[0]; 346cabdff1aSopenharmony_ci for (y = 0; y < avctx->height; y++) { 347cabdff1aSopenharmony_ci memset(dst, 0, avctx->width * 2); 348cabdff1aSopenharmony_ci dst += p->linesize[0]; 349cabdff1aSopenharmony_ci } 350cabdff1aSopenharmony_ci 351cabdff1aSopenharmony_ci dst = p->data[0]; 352cabdff1aSopenharmony_ci for (y = 0; y < avctx->height; y++) { 353cabdff1aSopenharmony_ci for (x = 0; x < avctx->width * 2 && y < avctx->height;) { 354cabdff1aSopenharmony_ci if (get_bits_left(&gb) <= 0) 355cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 356cabdff1aSopenharmony_ci 357cabdff1aSopenharmony_ci if (get_bits1(&gb)) { 358cabdff1aSopenharmony_ci int val = get_vlc2(&gb, s->vlc[0].table, YLC_VLC_BITS, 3); 359cabdff1aSopenharmony_ci if (val < 0) { 360cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 361cabdff1aSopenharmony_ci } else if (val < 0xE1) { 362cabdff1aSopenharmony_ci dst[x ] = table_y1[val]; 363cabdff1aSopenharmony_ci dst[x + 1] = table_u[val]; 364cabdff1aSopenharmony_ci dst[x + 2] = table_y2[val]; 365cabdff1aSopenharmony_ci dst[x + 3] = table_v[val]; 366cabdff1aSopenharmony_ci x += 4; 367cabdff1aSopenharmony_ci } else { 368cabdff1aSopenharmony_ci int incr = (val - 0xDF) * 4; 369cabdff1aSopenharmony_ci if (x + incr >= avctx->width * 2) { 370cabdff1aSopenharmony_ci int iy = ((x + incr) / (avctx->width * 2)); 371cabdff1aSopenharmony_ci x = (x + incr) % (avctx->width * 2); 372cabdff1aSopenharmony_ci y += iy; 373cabdff1aSopenharmony_ci dst += iy * p->linesize[0]; 374cabdff1aSopenharmony_ci } else { 375cabdff1aSopenharmony_ci x += incr; 376cabdff1aSopenharmony_ci } 377cabdff1aSopenharmony_ci } 378cabdff1aSopenharmony_ci } else { 379cabdff1aSopenharmony_ci int y1, y2, u, v; 380cabdff1aSopenharmony_ci 381cabdff1aSopenharmony_ci y1 = get_vlc2(&gb, s->vlc[1].table, YLC_VLC_BITS, 3); 382cabdff1aSopenharmony_ci u = get_vlc2(&gb, s->vlc[2].table, YLC_VLC_BITS, 3); 383cabdff1aSopenharmony_ci y2 = get_vlc2(&gb, s->vlc[1].table, YLC_VLC_BITS, 3); 384cabdff1aSopenharmony_ci v = get_vlc2(&gb, s->vlc[3].table, YLC_VLC_BITS, 3); 385cabdff1aSopenharmony_ci if (y1 < 0 || y2 < 0 || u < 0 || v < 0) 386cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 387cabdff1aSopenharmony_ci dst[x ] = y1; 388cabdff1aSopenharmony_ci dst[x + 1] = u; 389cabdff1aSopenharmony_ci dst[x + 2] = y1 + y2; 390cabdff1aSopenharmony_ci dst[x + 3] = v; 391cabdff1aSopenharmony_ci x += 4; 392cabdff1aSopenharmony_ci } 393cabdff1aSopenharmony_ci } 394cabdff1aSopenharmony_ci dst += p->linesize[0]; 395cabdff1aSopenharmony_ci } 396cabdff1aSopenharmony_ci 397cabdff1aSopenharmony_ci dst = p->data[0]; 398cabdff1aSopenharmony_ci for (x = 0; x < avctx->width * 2; x += 4) { 399cabdff1aSopenharmony_ci dst[x ] = dst[x ] + L[0]; 400cabdff1aSopenharmony_ci dst[x + 2] = L[0] = dst[x + 2] + L[0]; 401cabdff1aSopenharmony_ci L[1] = dst[x + 1] + L[1]; 402cabdff1aSopenharmony_ci dst[x + 1] = L[1]; 403cabdff1aSopenharmony_ci L[2] = dst[x + 3] + L[2]; 404cabdff1aSopenharmony_ci dst[x + 3] = L[2]; 405cabdff1aSopenharmony_ci } 406cabdff1aSopenharmony_ci dst += p->linesize[0]; 407cabdff1aSopenharmony_ci 408cabdff1aSopenharmony_ci for (y = 1; y < avctx->height; y++) { 409cabdff1aSopenharmony_ci x = 0; 410cabdff1aSopenharmony_ci dst[x ] = dst[x ] + L[0] + dst[x + 0 - p->linesize[0]] - TL[0]; 411cabdff1aSopenharmony_ci dst[x + 2] = L[0] = dst[x + 2] + L[0] + dst[x + 2 - p->linesize[0]] - TL[0]; 412cabdff1aSopenharmony_ci TL[0] = dst[x + 2 - p->linesize[0]]; 413cabdff1aSopenharmony_ci L[1] = dst[x + 1] + L[1] + dst[x + 1 - p->linesize[0]] - TL[1]; 414cabdff1aSopenharmony_ci dst[x + 1] = L[1]; 415cabdff1aSopenharmony_ci TL[1] = dst[x + 1 - p->linesize[0]]; 416cabdff1aSopenharmony_ci L[2] = dst[x + 3] + L[2] + dst[x + 3 - p->linesize[0]] - TL[2]; 417cabdff1aSopenharmony_ci dst[x + 3] = L[2]; 418cabdff1aSopenharmony_ci TL[2] = dst[x + 3 - p->linesize[0]]; 419cabdff1aSopenharmony_ci for (x = 4; x < avctx->width * 2; x += 4) { 420cabdff1aSopenharmony_ci dst[x ] = dst[x ] + L[0] + dst[x + 0 - p->linesize[0]] - TL[0]; 421cabdff1aSopenharmony_ci dst[x + 2] = L[0] = dst[x + 2] + L[0] + dst[x + 2 - p->linesize[0]] - TL[0]; 422cabdff1aSopenharmony_ci TL[0] = dst[x + 2 - p->linesize[0]]; 423cabdff1aSopenharmony_ci L[1] = dst[x + 1] + L[1] + dst[x + 1 - p->linesize[0]] - TL[1]; 424cabdff1aSopenharmony_ci dst[x + 1] = L[1]; 425cabdff1aSopenharmony_ci TL[1] = dst[x + 1 - p->linesize[0]]; 426cabdff1aSopenharmony_ci L[2] = dst[x + 3] + L[2] + dst[x + 3 - p->linesize[0]] - TL[2]; 427cabdff1aSopenharmony_ci dst[x + 3] = L[2]; 428cabdff1aSopenharmony_ci TL[2] = dst[x + 3 - p->linesize[0]]; 429cabdff1aSopenharmony_ci } 430cabdff1aSopenharmony_ci dst += p->linesize[0]; 431cabdff1aSopenharmony_ci } 432cabdff1aSopenharmony_ci 433cabdff1aSopenharmony_ci p->pict_type = AV_PICTURE_TYPE_I; 434cabdff1aSopenharmony_ci p->key_frame = 1; 435cabdff1aSopenharmony_ci *got_frame = 1; 436cabdff1aSopenharmony_ci 437cabdff1aSopenharmony_ci return avpkt->size; 438cabdff1aSopenharmony_ci} 439cabdff1aSopenharmony_ci 440cabdff1aSopenharmony_cistatic av_cold int decode_end(AVCodecContext *avctx) 441cabdff1aSopenharmony_ci{ 442cabdff1aSopenharmony_ci YLCContext *s = avctx->priv_data; 443cabdff1aSopenharmony_ci 444cabdff1aSopenharmony_ci for (int i = 0; i < FF_ARRAY_ELEMS(s->vlc); i++) 445cabdff1aSopenharmony_ci ff_free_vlc(&s->vlc[i]); 446cabdff1aSopenharmony_ci av_freep(&s->buffer); 447cabdff1aSopenharmony_ci s->buffer_size = 0; 448cabdff1aSopenharmony_ci 449cabdff1aSopenharmony_ci return 0; 450cabdff1aSopenharmony_ci} 451cabdff1aSopenharmony_ci 452cabdff1aSopenharmony_ciconst FFCodec ff_ylc_decoder = { 453cabdff1aSopenharmony_ci .p.name = "ylc", 454cabdff1aSopenharmony_ci .p.long_name = NULL_IF_CONFIG_SMALL("YUY2 Lossless Codec"), 455cabdff1aSopenharmony_ci .p.type = AVMEDIA_TYPE_VIDEO, 456cabdff1aSopenharmony_ci .p.id = AV_CODEC_ID_YLC, 457cabdff1aSopenharmony_ci .priv_data_size = sizeof(YLCContext), 458cabdff1aSopenharmony_ci .init = decode_init, 459cabdff1aSopenharmony_ci .close = decode_end, 460cabdff1aSopenharmony_ci FF_CODEC_DECODE_CB(decode_frame), 461cabdff1aSopenharmony_ci .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS, 462cabdff1aSopenharmony_ci .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, 463cabdff1aSopenharmony_ci}; 464