1/* 2 * Gremlin Digital Video (GDV) decoder 3 * Copyright (c) 2017 Konstantin Shishkov 4 * Copyright (c) 2017 Paul B Mahol 5 * 6 * This file is part of FFmpeg. 7 * 8 * FFmpeg is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU Lesser General Public 10 * License as published by the Free Software Foundation; either 11 * version 2.1 of the License, or (at your option) any later version. 12 * 13 * FFmpeg is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * Lesser General Public License for more details. 17 * 18 * You should have received a copy of the GNU Lesser General Public 19 * License along with FFmpeg; if not, write to the Free Software 20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 21 */ 22 23#include "libavutil/common.h" 24#include "avcodec.h" 25#include "bytestream.h" 26#include "codec_internal.h" 27#include "decode.h" 28#include "internal.h" 29 30typedef struct GDVContext { 31 AVCodecContext *avctx; 32 33 GetByteContext gb; 34 GetByteContext g2; 35 PutByteContext pb; 36 37 uint32_t pal[256]; 38 uint8_t *frame; 39 unsigned frame_size; 40 unsigned scale_h, scale_v; 41} GDVContext; 42 43typedef struct Bits8 { 44 uint8_t queue; 45 uint8_t fill; 46} Bits8; 47 48typedef struct Bits32 { 49 uint32_t queue; 50 uint8_t fill; 51} Bits32; 52 53#define PREAMBLE_SIZE 4096 54 55static av_cold int gdv_decode_init(AVCodecContext *avctx) 56{ 57 GDVContext *gdv = avctx->priv_data; 58 int i, j, k; 59 60 avctx->pix_fmt = AV_PIX_FMT_PAL8; 61 gdv->frame_size = avctx->width * avctx->height + PREAMBLE_SIZE; 62 gdv->frame = av_calloc(gdv->frame_size, 1); 63 if (!gdv->frame) 64 return AVERROR(ENOMEM); 65 66 for (i = 0; i < 2; i++) { 67 for (j = 0; j < 256; j++) { 68 for (k = 0; k < 8; k++) { 69 gdv->frame[i * 2048 + j * 8 + k] = j; 70 } 71 } 72 } 73 74 return 0; 75} 76 77static void scaleup(uint8_t *dst, const uint8_t *src, int w) 78{ 79 int x; 80 for (x = 0; x < w - 7; x+=8) { 81 dst[x + 0] = 82 dst[x + 1] = src[(x>>1) + 0]; 83 dst[x + 2] = 84 dst[x + 3] = src[(x>>1) + 1]; 85 dst[x + 4] = 86 dst[x + 5] = src[(x>>1) + 2]; 87 dst[x + 6] = 88 dst[x + 7] = src[(x>>1) + 3]; 89 } 90 for (; x < w; x++) { 91 dst[x] = src[(x>>1)]; 92 } 93} 94 95static void scaleup_rev(uint8_t *dst, const uint8_t *src, int w) 96{ 97 int x; 98 99 for (x = w - 1; (x+1) & 7; x--) { 100 dst[x] = src[(x>>1)]; 101 } 102 for (x -= 7; x >= 0; x -= 8) { 103 dst[x + 6] = 104 dst[x + 7] = src[(x>>1) + 3]; 105 dst[x + 4] = 106 dst[x + 5] = src[(x>>1) + 2]; 107 dst[x + 2] = 108 dst[x + 3] = src[(x>>1) + 1]; 109 dst[x + 0] = 110 dst[x + 1] = src[(x>>1) + 0]; 111 } 112} 113 114static void scaledown(uint8_t *dst, const uint8_t *src, int w) 115{ 116 int x; 117 for (x = 0; x < w - 7; x+=8) { 118 dst[x + 0] = src[2*x + 0]; 119 dst[x + 1] = src[2*x + 2]; 120 dst[x + 2] = src[2*x + 4]; 121 dst[x + 3] = src[2*x + 6]; 122 dst[x + 4] = src[2*x + 8]; 123 dst[x + 5] = src[2*x +10]; 124 dst[x + 6] = src[2*x +12]; 125 dst[x + 7] = src[2*x +14]; 126 } 127 for (; x < w; x++) { 128 dst[x] = src[2*x]; 129 } 130} 131 132static void rescale(GDVContext *gdv, uint8_t *dst, int w, int h, int scale_v, int scale_h) 133{ 134 int j, y; 135 136 if ((gdv->scale_v == scale_v) && (gdv->scale_h == scale_h)) { 137 return; 138 } 139 140 if (gdv->scale_v) { 141 for (j = 0; j < h; j++) { 142 int y = h - j - 1; 143 uint8_t *dst1 = dst + PREAMBLE_SIZE + y * w; 144 uint8_t *src1 = dst + PREAMBLE_SIZE + (y>>!!gdv->scale_h) * (w>>1); 145 146 scaleup_rev(dst1, src1, w); 147 } 148 } else if (gdv->scale_h) { 149 for (j = 0; j < h; j++) { 150 int y = h - j - 1; 151 uint8_t *dst1 = dst + PREAMBLE_SIZE + y * w; 152 uint8_t *src1 = dst + PREAMBLE_SIZE + (y>>1) * w; 153 memcpy(dst1, src1, w); 154 } 155 } 156 157 if (scale_h && scale_v) { 158 for (y = 0; y < (h>>1); y++) { 159 uint8_t *dst1 = dst + PREAMBLE_SIZE + y * (w>>1); 160 uint8_t *src1 = dst + PREAMBLE_SIZE + y*2 * w; 161 scaledown(dst1, src1, w>>1); 162 } 163 } else if (scale_h) { 164 for (y = 0; y < (h>>1); y++) { 165 uint8_t *dst1 = dst + PREAMBLE_SIZE + y * w; 166 uint8_t *src1 = dst + PREAMBLE_SIZE + y*2 * w; 167 memcpy(dst1, src1, w); 168 } 169 } else if (scale_v) { 170 for (y = 0; y < h; y++) { 171 uint8_t *dst1 = dst + PREAMBLE_SIZE + y * w; 172 scaledown(dst1, dst1, w>>1); 173 } 174 } 175 176 gdv->scale_v = scale_v; 177 gdv->scale_h = scale_h; 178} 179 180static int read_bits2(Bits8 *bits, GetByteContext *gb) 181{ 182 int res; 183 184 if (bits->fill == 0) { 185 bits->queue |= bytestream2_get_byte(gb); 186 bits->fill = 8; 187 } 188 res = bits->queue >> 6; 189 bits->queue <<= 2; 190 bits->fill -= 2; 191 192 return res; 193} 194 195static void fill_bits32(Bits32 *bits, GetByteContext *gb) 196{ 197 bits->queue = bytestream2_get_le32(gb); 198 bits->fill = 32; 199} 200 201static int read_bits32(Bits32 *bits, GetByteContext *gb, int nbits) 202{ 203 int res = bits->queue & ((1 << nbits) - 1); 204 205 bits->queue >>= nbits; 206 bits->fill -= nbits; 207 if (bits->fill <= 16) { 208 bits->queue |= bytestream2_get_le16(gb) << bits->fill; 209 bits->fill += 16; 210 } 211 212 return res; 213} 214 215static void lz_copy(PutByteContext *pb, GetByteContext *g2, int offset, unsigned len) 216{ 217 int i; 218 219 if (offset == -1) { 220 int c; 221 222 bytestream2_seek(g2, bytestream2_tell_p(pb) - 1, SEEK_SET); 223 c = bytestream2_get_byte(g2); 224 for (i = 0; i < len; i++) { 225 bytestream2_put_byte(pb, c); 226 } 227 } else if (offset < 0) { 228 int start = bytestream2_tell_p(pb) - (-offset); 229 230 bytestream2_seek(g2, start, SEEK_SET); 231 for (i = 0; i < len; i++) { 232 bytestream2_put_byte(pb, bytestream2_get_byte(g2)); 233 } 234 } else { 235 int start = bytestream2_tell_p(pb) + offset; 236 237 bytestream2_seek(g2, start, SEEK_SET); 238 for (i = 0; i < len; i++) { 239 bytestream2_put_byte(pb, bytestream2_get_byte(g2)); 240 } 241 } 242} 243 244static int decompress_2(AVCodecContext *avctx) 245{ 246 GDVContext *gdv = avctx->priv_data; 247 GetByteContext *gb = &gdv->gb; 248 GetByteContext *g2 = &gdv->g2; 249 PutByteContext *pb = &gdv->pb; 250 Bits8 bits = { 0 }; 251 int c, i; 252 253 bytestream2_init(g2, gdv->frame, gdv->frame_size); 254 bytestream2_skip_p(pb, PREAMBLE_SIZE); 255 256 for (c = 0; c < 256; c++) { 257 for (i = 0; i < 16; i++) { 258 gdv->frame[c * 16 + i] = c; 259 } 260 } 261 262 while (bytestream2_get_bytes_left_p(pb) > 0 && bytestream2_get_bytes_left(gb) > 0) { 263 int tag = read_bits2(&bits, gb); 264 if (tag == 0) { 265 bytestream2_put_byte(pb, bytestream2_get_byte(gb)); 266 } else if (tag == 1) { 267 int b = bytestream2_get_byte(gb); 268 int len = (b & 0xF) + 3; 269 int top = (b >> 4) & 0xF; 270 int off = (bytestream2_get_byte(gb) << 4) + top - 4096; 271 lz_copy(pb, g2, off, len); 272 } else if (tag == 2) { 273 int len = (bytestream2_get_byte(gb)) + 2; 274 bytestream2_skip_p(pb, len); 275 } else { 276 break; 277 } 278 } 279 280 if (bytestream2_get_bytes_left_p(pb) > 0) 281 return AVERROR_INVALIDDATA; 282 283 return 0; 284} 285 286static int decompress_5(AVCodecContext *avctx, unsigned skip) 287{ 288 GDVContext *gdv = avctx->priv_data; 289 GetByteContext *gb = &gdv->gb; 290 GetByteContext *g2 = &gdv->g2; 291 PutByteContext *pb = &gdv->pb; 292 Bits8 bits = { 0 }; 293 294 bytestream2_init(g2, gdv->frame, gdv->frame_size); 295 bytestream2_skip_p(pb, skip + PREAMBLE_SIZE); 296 297 while (bytestream2_get_bytes_left_p(pb) > 0 && bytestream2_get_bytes_left(gb) > 0) { 298 int tag = read_bits2(&bits, gb); 299 if (bytestream2_get_bytes_left(gb) < 1) 300 return AVERROR_INVALIDDATA; 301 if (tag == 0) { 302 bytestream2_put_byte(pb, bytestream2_get_byte(gb)); 303 } else if (tag == 1) { 304 int b = bytestream2_get_byte(gb); 305 int len = (b & 0xF) + 3; 306 int top = b >> 4; 307 int off = (bytestream2_get_byte(gb) << 4) + top - 4096; 308 lz_copy(pb, g2, off, len); 309 } else if (tag == 2) { 310 int len; 311 int b = bytestream2_get_byte(gb); 312 if (b == 0) { 313 return 0; 314 } 315 if (b != 0xFF) { 316 len = b; 317 } else { 318 len = bytestream2_get_le16(gb); 319 } 320 bytestream2_skip_p(pb, len + 1); 321 } else { 322 int b = bytestream2_get_byte(gb); 323 int len = (b & 0x3) + 2; 324 int off = -(b >> 2) - 1; 325 lz_copy(pb, g2, off, len); 326 } 327 } 328 if (bytestream2_get_bytes_left_p(pb) > 0) 329 return AVERROR_INVALIDDATA; 330 return 0; 331} 332 333static int decompress_68(AVCodecContext *avctx, unsigned skip, unsigned use8) 334{ 335 GDVContext *gdv = avctx->priv_data; 336 GetByteContext *gb = &gdv->gb; 337 GetByteContext *g2 = &gdv->g2; 338 PutByteContext *pb = &gdv->pb; 339 Bits32 bits; 340 341 bytestream2_init(g2, gdv->frame, gdv->frame_size); 342 bytestream2_skip_p(pb, skip + PREAMBLE_SIZE); 343 fill_bits32(&bits, gb); 344 345 while (bytestream2_get_bytes_left_p(pb) > 0 && bytestream2_get_bytes_left(gb) > 0) { 346 int tag = read_bits32(&bits, gb, 2); 347 if (tag == 0) { 348 int b = read_bits32(&bits, gb, 1); 349 if (b == 0) { 350 bytestream2_put_byte(pb, bytestream2_get_byte(gb)); 351 } else { 352 int i, len = 2; 353 int lbits = 0; 354 while (1) { 355 int val; 356 357 lbits += 1; 358 val = read_bits32(&bits, gb, lbits); 359 len += val; 360 if (val != ((1 << lbits) - 1)) { 361 break; 362 } 363 if (lbits >= 16) 364 return AVERROR_INVALIDDATA; 365 } 366 for (i = 0; i < len; i++) { 367 bytestream2_put_byte(pb, bytestream2_get_byte(gb)); 368 } 369 } 370 } else if (tag == 1) { 371 int b = read_bits32(&bits, gb, 1); 372 int len; 373 374 if (b == 0) { 375 len = (read_bits32(&bits, gb, 4)) + 2; 376 } else { 377 int bb = bytestream2_get_byte(gb); 378 if ((bb & 0x80) == 0) { 379 len = bb + 18; 380 } else { 381 int top = (bb & 0x7F) << 8; 382 len = top + bytestream2_get_byte(gb) + 146; 383 } 384 } 385 bytestream2_skip_p(pb, len); 386 } else if (tag == 2) { 387 int i, subtag = read_bits32(&bits, gb, 2); 388 389 if (subtag != 3) { 390 int top = (read_bits32(&bits, gb, 4)) << 8; 391 int offs = top + bytestream2_get_byte(gb); 392 if ((subtag != 0) || (offs <= 0xF80)) { 393 int len = (subtag) + 3; 394 lz_copy(pb, g2, (offs) - 4096, len); 395 } else { 396 int real_off, len, c1, c2; 397 398 if (offs == 0xFFF) { 399 return 0; 400 } 401 402 real_off = ((offs >> 4) & 0x7) + 1; 403 len = ((offs & 0xF) + 2) * 2; 404 c1 = gdv->frame[bytestream2_tell_p(pb) - real_off]; 405 c2 = gdv->frame[bytestream2_tell_p(pb) - real_off + 1]; 406 for (i = 0; i < len/2; i++) { 407 bytestream2_put_byte(pb, c1); 408 bytestream2_put_byte(pb, c2); 409 } 410 } 411 } else { 412 int b = bytestream2_get_byte(gb); 413 int off = ((b & 0x7F)) + 1; 414 int len = ((b & 0x80) == 0) ? 2 : 3; 415 416 lz_copy(pb, g2, -off, len); 417 } 418 } else { 419 int len; 420 int off; 421 if (use8) { 422 int q, b = bytestream2_get_byte(gb); 423 if ((b & 0xC0) == 0xC0) { 424 len = ((b & 0x3F)) + 8; 425 q = read_bits32(&bits, gb, 4); 426 off = (q << 8) + (bytestream2_get_byte(gb)) + 1; 427 } else { 428 int ofs1; 429 if ((b & 0x80) == 0) { 430 len = ((b >> 4)) + 6; 431 ofs1 = (b & 0xF); 432 } else { 433 len = ((b & 0x3F)) + 14; 434 ofs1 = read_bits32(&bits, gb, 4); 435 } 436 off = (ofs1 << 8) + (bytestream2_get_byte(gb)) - 4096; 437 } 438 } else { 439 int ofs1, b = bytestream2_get_byte(gb); 440 441 if ((b >> 4) == 0xF) { 442 len = bytestream2_get_byte(gb) + 21; 443 } else { 444 len = (b >> 4) + 6; 445 } 446 ofs1 = (b & 0xF); 447 off = (ofs1 << 8) + bytestream2_get_byte(gb) - 4096; 448 } 449 lz_copy(pb, g2, off, len); 450 } 451 } 452 453 if (bytestream2_get_bytes_left_p(pb) > 0) 454 return AVERROR_INVALIDDATA; 455 456 return 0; 457} 458 459static int gdv_decode_frame(AVCodecContext *avctx, AVFrame *frame, 460 int *got_frame, AVPacket *avpkt) 461{ 462 GDVContext *gdv = avctx->priv_data; 463 GetByteContext *gb = &gdv->gb; 464 PutByteContext *pb = &gdv->pb; 465 int ret, i; 466 int compression; 467 unsigned flags; 468 uint8_t *dst; 469 470 bytestream2_init(gb, avpkt->data, avpkt->size); 471 bytestream2_init_writer(pb, gdv->frame, gdv->frame_size); 472 473 flags = bytestream2_get_le32(gb); 474 compression = flags & 0xF; 475 476 if (compression == 4 || compression == 7 || compression > 8) 477 return AVERROR_INVALIDDATA; 478 479 if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) 480 return ret; 481 ff_copy_palette(gdv->pal, avpkt, avctx); 482 483 if (compression < 2 && bytestream2_get_bytes_left(gb) < 256*3) 484 return AVERROR_INVALIDDATA; 485 rescale(gdv, gdv->frame, avctx->width, avctx->height, 486 !!(flags & 0x10), !!(flags & 0x20)); 487 488 switch (compression) { 489 case 1: 490 memset(gdv->frame + PREAMBLE_SIZE, 0, gdv->frame_size - PREAMBLE_SIZE); 491 case 0: 492 for (i = 0; i < 256; i++) { 493 unsigned r = bytestream2_get_byte(gb); 494 unsigned g = bytestream2_get_byte(gb); 495 unsigned b = bytestream2_get_byte(gb); 496 gdv->pal[i] = 0xFFU << 24 | r << 18 | g << 10 | b << 2; 497 } 498 break; 499 case 2: 500 ret = decompress_2(avctx); 501 break; 502 case 3: 503 break; 504 case 5: 505 ret = decompress_5(avctx, flags >> 8); 506 break; 507 case 6: 508 ret = decompress_68(avctx, flags >> 8, 0); 509 break; 510 case 8: 511 ret = decompress_68(avctx, flags >> 8, 1); 512 break; 513 default: 514 av_assert0(0); 515 } 516 if (ret < 0) 517 return ret; 518 519 memcpy(frame->data[1], gdv->pal, AVPALETTE_SIZE); 520 dst = frame->data[0]; 521 522 if (!gdv->scale_v && !gdv->scale_h) { 523 int sidx = PREAMBLE_SIZE, didx = 0; 524 int y; 525 526 for (y = 0; y < avctx->height; y++) { 527 memcpy(dst + didx, gdv->frame + sidx, avctx->width); 528 sidx += avctx->width; 529 didx += frame->linesize[0]; 530 } 531 } else { 532 int sidx = PREAMBLE_SIZE, didx = 0; 533 int y; 534 535 for (y = 0; y < avctx->height; y++) { 536 if (!gdv->scale_v) { 537 memcpy(dst + didx, gdv->frame + sidx, avctx->width); 538 } else { 539 uint8_t *dst2 = dst + didx; 540 uint8_t *src2 = gdv->frame + sidx; 541 542 scaleup(dst2, src2, avctx->width); 543 } 544 if (!gdv->scale_h || ((y & 1) == 1)) { 545 sidx += !gdv->scale_v ? avctx->width : avctx->width/2; 546 } 547 didx += frame->linesize[0]; 548 } 549 } 550 551 *got_frame = 1; 552 553 return avpkt->size; 554} 555 556static av_cold int gdv_decode_close(AVCodecContext *avctx) 557{ 558 GDVContext *gdv = avctx->priv_data; 559 av_freep(&gdv->frame); 560 return 0; 561} 562 563const FFCodec ff_gdv_decoder = { 564 .p.name = "gdv", 565 .p.long_name = NULL_IF_CONFIG_SMALL("Gremlin Digital Video"), 566 .p.type = AVMEDIA_TYPE_VIDEO, 567 .p.id = AV_CODEC_ID_GDV, 568 .priv_data_size = sizeof(GDVContext), 569 .init = gdv_decode_init, 570 .close = gdv_decode_close, 571 FF_CODEC_DECODE_CB(gdv_decode_frame), 572 .p.capabilities = AV_CODEC_CAP_DR1, 573 .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, 574}; 575