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