1/* 2 * NotchLC decoder 3 * Copyright (c) 2020 Paul B Mahol 4 * 5 * This file is part of FFmpeg. 6 * 7 * FFmpeg is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * FFmpeg is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with FFmpeg; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 */ 21 22#include <stdio.h> 23#include <stdlib.h> 24#include <string.h> 25 26#define BITSTREAM_READER_LE 27#include "libavutil/intreadwrite.h" 28#include "avcodec.h" 29#include "bytestream.h" 30#include "codec_internal.h" 31#include "get_bits.h" 32#include "internal.h" 33#include "lzf.h" 34#include "thread.h" 35 36typedef struct NotchLCContext { 37 unsigned compressed_size; 38 unsigned format; 39 40 uint8_t *uncompressed_buffer; 41 unsigned uncompressed_size; 42 43 uint8_t *lzf_buffer; 44 int64_t lzf_size; 45 46 unsigned texture_size_x; 47 unsigned texture_size_y; 48 unsigned y_data_row_offsets; 49 unsigned uv_offset_data_offset; 50 unsigned y_control_data_offset; 51 unsigned a_control_word_offset; 52 unsigned y_data_offset; 53 unsigned uv_data_offset; 54 unsigned y_data_size; 55 unsigned a_data_offset; 56 unsigned uv_count_offset; 57 unsigned a_count_size; 58 unsigned data_end; 59 60 GetByteContext gb; 61 PutByteContext pb; 62} NotchLCContext; 63 64static av_cold int decode_init(AVCodecContext *avctx) 65{ 66 avctx->pix_fmt = AV_PIX_FMT_YUVA444P12; 67 avctx->color_range = AVCOL_RANGE_JPEG; 68 avctx->colorspace = AVCOL_SPC_RGB; 69 avctx->color_primaries = AVCOL_PRI_BT709; 70 avctx->color_trc = AVCOL_TRC_IEC61966_2_1; 71 72 return 0; 73} 74 75#define HISTORY_SIZE (64 * 1024) 76 77static int lz4_decompress(AVCodecContext *avctx, 78 GetByteContext *gb, 79 PutByteContext *pb) 80{ 81 unsigned reference_pos, match_length, delta, pos = 0; 82 uint8_t history[64 * 1024]; 83 84 while (bytestream2_get_bytes_left(gb) > 0) { 85 uint8_t token = bytestream2_get_byte(gb); 86 unsigned num_literals = token >> 4; 87 88 if (num_literals == 15) { 89 unsigned char current; 90 do { 91 current = bytestream2_get_byte(gb); 92 num_literals += current; 93 } while (current == 255); 94 } 95 96 if (pos + num_literals < HISTORY_SIZE) { 97 bytestream2_get_buffer(gb, history + pos, num_literals); 98 pos += num_literals; 99 } else { 100 while (num_literals-- > 0) { 101 history[pos++] = bytestream2_get_byte(gb); 102 if (pos == HISTORY_SIZE) { 103 bytestream2_put_buffer(pb, history, HISTORY_SIZE); 104 pos = 0; 105 } 106 } 107 } 108 109 if (bytestream2_get_bytes_left(gb) <= 0) 110 break; 111 112 delta = bytestream2_get_le16(gb); 113 if (delta == 0) 114 return 0; 115 match_length = 4 + (token & 0x0F); 116 if (match_length == 4 + 0x0F) { 117 uint8_t current; 118 119 do { 120 current = bytestream2_get_byte(gb); 121 match_length += current; 122 } while (current == 255); 123 } 124 reference_pos = (pos >= delta) ? (pos - delta) : (HISTORY_SIZE + pos - delta); 125 if (pos + match_length < HISTORY_SIZE && reference_pos + match_length < HISTORY_SIZE) { 126 if (pos >= reference_pos + match_length || reference_pos >= pos + match_length) { 127 memcpy(history + pos, history + reference_pos, match_length); 128 pos += match_length; 129 } else { 130 while (match_length-- > 0) 131 history[pos++] = history[reference_pos++]; 132 } 133 } else { 134 while (match_length-- > 0) { 135 history[pos++] = history[reference_pos++]; 136 if (pos == HISTORY_SIZE) { 137 bytestream2_put_buffer(pb, history, HISTORY_SIZE); 138 pos = 0; 139 } 140 reference_pos %= HISTORY_SIZE; 141 } 142 } 143 } 144 145 bytestream2_put_buffer(pb, history, pos); 146 147 return bytestream2_tell_p(pb); 148} 149 150static int decode_blocks(AVCodecContext *avctx, AVFrame *p, 151 unsigned uncompressed_size) 152{ 153 NotchLCContext *s = avctx->priv_data; 154 GetByteContext rgb, dgb, *gb = &s->gb; 155 GetBitContext bit; 156 int ylinesize, ulinesize, vlinesize, alinesize; 157 uint16_t *dsty, *dstu, *dstv, *dsta; 158 int ret; 159 160 s->texture_size_x = bytestream2_get_le32(gb); 161 s->texture_size_y = bytestream2_get_le32(gb); 162 163 ret = ff_set_dimensions(avctx, s->texture_size_x, s->texture_size_y); 164 if (ret < 0) 165 return ret; 166 167 s->uv_offset_data_offset = bytestream2_get_le32(gb); 168 if (s->uv_offset_data_offset >= UINT_MAX / 4) 169 return AVERROR_INVALIDDATA; 170 s->uv_offset_data_offset *= 4; 171 if (s->uv_offset_data_offset >= uncompressed_size) 172 return AVERROR_INVALIDDATA; 173 174 s->y_control_data_offset = bytestream2_get_le32(gb); 175 if (s->y_control_data_offset >= UINT_MAX / 4) 176 return AVERROR_INVALIDDATA; 177 s->y_control_data_offset *= 4; 178 if (s->y_control_data_offset >= uncompressed_size) 179 return AVERROR_INVALIDDATA; 180 181 s->a_control_word_offset = bytestream2_get_le32(gb); 182 if (s->a_control_word_offset >= UINT_MAX / 4) 183 return AVERROR_INVALIDDATA; 184 s->a_control_word_offset *= 4; 185 if (s->a_control_word_offset >= uncompressed_size) 186 return AVERROR_INVALIDDATA; 187 188 s->uv_data_offset = bytestream2_get_le32(gb); 189 if (s->uv_data_offset >= UINT_MAX / 4) 190 return AVERROR_INVALIDDATA; 191 s->uv_data_offset *= 4; 192 if (s->uv_data_offset >= uncompressed_size) 193 return AVERROR_INVALIDDATA; 194 195 s->y_data_size = bytestream2_get_le32(gb); 196 if (s->y_data_size >= UINT_MAX / 4) 197 return AVERROR_INVALIDDATA; 198 199 s->a_data_offset = bytestream2_get_le32(gb); 200 if (s->a_data_offset >= UINT_MAX / 4) 201 return AVERROR_INVALIDDATA; 202 s->a_data_offset *= 4; 203 if (s->a_data_offset >= uncompressed_size) 204 return AVERROR_INVALIDDATA; 205 206 s->a_count_size = bytestream2_get_le32(gb); 207 if (s->a_count_size >= UINT_MAX / 4) 208 return AVERROR_INVALIDDATA; 209 s->a_count_size *= 4; 210 if (s->a_count_size >= uncompressed_size) 211 return AVERROR_INVALIDDATA; 212 213 s->data_end = bytestream2_get_le32(gb); 214 if (s->data_end > uncompressed_size) 215 return AVERROR_INVALIDDATA; 216 217 s->y_data_row_offsets = bytestream2_tell(gb); 218 if (s->data_end <= s->y_data_size) 219 return AVERROR_INVALIDDATA; 220 s->y_data_offset = s->data_end - s->y_data_size; 221 if (s->y_data_offset <= s->a_data_offset) 222 return AVERROR_INVALIDDATA; 223 s->uv_count_offset = s->y_data_offset - s->a_data_offset; 224 225 if ((ret = ff_thread_get_buffer(avctx, p, 0)) < 0) 226 return ret; 227 228 rgb = *gb; 229 dgb = *gb; 230 bytestream2_seek(&rgb, s->y_data_row_offsets, SEEK_SET); 231 bytestream2_seek(gb, s->y_control_data_offset, SEEK_SET); 232 233 if (bytestream2_get_bytes_left(gb) < (avctx->height + 3) / 4 * ((avctx->width + 3) / 4) * 4) 234 return AVERROR_INVALIDDATA; 235 236 dsty = (uint16_t *)p->data[0]; 237 dsta = (uint16_t *)p->data[3]; 238 ylinesize = p->linesize[0] / 2; 239 alinesize = p->linesize[3] / 2; 240 241 for (int y = 0; y < avctx->height; y += 4) { 242 const unsigned row_offset = bytestream2_get_le32(&rgb); 243 244 bytestream2_seek(&dgb, s->y_data_offset + row_offset, SEEK_SET); 245 246 init_get_bits8(&bit, dgb.buffer, bytestream2_get_bytes_left(&dgb)); 247 for (int x = 0; x < avctx->width; x += 4) { 248 unsigned item = bytestream2_get_le32(gb); 249 unsigned y_min = item & 4095; 250 unsigned y_max = (item >> 12) & 4095; 251 unsigned y_diff = y_max - y_min; 252 unsigned control[4]; 253 254 control[0] = (item >> 24) & 3; 255 control[1] = (item >> 26) & 3; 256 control[2] = (item >> 28) & 3; 257 control[3] = (item >> 30) & 3; 258 259 for (int i = 0; i < 4; i++) { 260 const int nb_bits = control[i] + 1; 261 const int div = (1 << nb_bits) - 1; 262 const int add = div - 1; 263 264 dsty[x + i * ylinesize + 0] = av_clip_uintp2(y_min + ((y_diff * get_bits(&bit, nb_bits) + add) / div), 12); 265 dsty[x + i * ylinesize + 1] = av_clip_uintp2(y_min + ((y_diff * get_bits(&bit, nb_bits) + add) / div), 12); 266 dsty[x + i * ylinesize + 2] = av_clip_uintp2(y_min + ((y_diff * get_bits(&bit, nb_bits) + add) / div), 12); 267 dsty[x + i * ylinesize + 3] = av_clip_uintp2(y_min + ((y_diff * get_bits(&bit, nb_bits) + add) / div), 12); 268 } 269 } 270 271 dsty += 4 * ylinesize; 272 } 273 274 rgb = *gb; 275 dgb = *gb; 276 bytestream2_seek(gb, s->a_control_word_offset, SEEK_SET); 277 if (s->uv_count_offset == s->a_control_word_offset) { 278 for (int y = 0; y < avctx->height; y++) { 279 for (int x = 0; x < avctx->width; x++) 280 dsta[x] = 4095; 281 dsta += alinesize; 282 } 283 } else { 284 if (bytestream2_get_bytes_left(gb) < (avctx->height + 15) / 16 * ((avctx->width + 15) / 16) * 8) 285 return AVERROR_INVALIDDATA; 286 287 for (int y = 0; y < avctx->height; y += 16) { 288 for (int x = 0; x < avctx->width; x += 16) { 289 unsigned m = bytestream2_get_le32(gb); 290 unsigned offset = bytestream2_get_le32(gb); 291 unsigned alpha0, alpha1; 292 uint64_t control; 293 294 if (offset >= UINT_MAX / 4) 295 return AVERROR_INVALIDDATA; 296 offset = offset * 4 + s->uv_data_offset + s->a_data_offset; 297 if (offset >= s->data_end) 298 return AVERROR_INVALIDDATA; 299 300 bytestream2_seek(&dgb, offset, SEEK_SET); 301 control = bytestream2_get_le64(&dgb); 302 alpha0 = control & 0xFF; 303 alpha1 = (control >> 8) & 0xFF; 304 control = control >> 16; 305 306 for (int by = 0; by < 4; by++) { 307 for (int bx = 0; bx < 4; bx++) { 308 switch (m & 3) { 309 case 0: 310 for (int i = 0; i < 4; i++) { 311 for (int j = 0; j < 4; j++) { 312 dsta[x + (i + by * 4) * alinesize + bx * 4 + j] = 0; 313 } 314 } 315 break; 316 case 1: 317 for (int i = 0; i < 4; i++) { 318 for (int j = 0; j < 4; j++) { 319 dsta[x + (i + by * 4) * alinesize + bx * 4 + j] = 4095; 320 } 321 } 322 break; 323 case 2: 324 for (int i = 0; i < 4; i++) { 325 for (int j = 0; j < 4; j++) { 326 dsta[x + (i + by * 4) * alinesize + bx * 4 + j] = (alpha0 + (alpha1 - alpha0) * (control & 7)) << 4; 327 } 328 } 329 break; 330 default: 331 return AVERROR_INVALIDDATA; 332 } 333 334 control >>= 3; 335 m >>= 2; 336 } 337 } 338 } 339 340 dsta += 16 * alinesize; 341 } 342 } 343 344 bytestream2_seek(&rgb, s->uv_offset_data_offset, SEEK_SET); 345 346 dstu = (uint16_t *)p->data[1]; 347 dstv = (uint16_t *)p->data[2]; 348 ulinesize = p->linesize[1] / 2; 349 vlinesize = p->linesize[2] / 2; 350 351 for (int y = 0; y < avctx->height; y += 16) { 352 for (int x = 0; x < avctx->width; x += 16) { 353 unsigned offset = bytestream2_get_le32(&rgb) * 4; 354 int u[16][16] = { 0 }, v[16][16] = { 0 }; 355 int u0, v0, u1, v1, udif, vdif; 356 unsigned escape, is8x8, loc; 357 358 bytestream2_seek(&dgb, s->uv_data_offset + offset, SEEK_SET); 359 360 is8x8 = bytestream2_get_le16(&dgb); 361 escape = bytestream2_get_le16(&dgb); 362 363 if (escape == 0 && is8x8 == 0) { 364 u0 = bytestream2_get_byte(&dgb); 365 v0 = bytestream2_get_byte(&dgb); 366 u1 = bytestream2_get_byte(&dgb); 367 v1 = bytestream2_get_byte(&dgb); 368 loc = bytestream2_get_le32(&dgb); 369 u0 = (u0 << 4) | (u0 & 0xF); 370 v0 = (v0 << 4) | (v0 & 0xF); 371 u1 = (u1 << 4) | (u1 & 0xF); 372 v1 = (v1 << 4) | (v1 & 0xF); 373 udif = u1 - u0; 374 vdif = v1 - v0; 375 376 for (int i = 0; i < 16; i += 4) { 377 for (int j = 0; j < 16; j += 4) { 378 for (int ii = 0; ii < 4; ii++) { 379 for (int jj = 0; jj < 4; jj++) { 380 u[i + ii][j + jj] = u0 + ((udif * (int)(loc & 3) + 2) / 3); 381 v[i + ii][j + jj] = v0 + ((vdif * (int)(loc & 3) + 2) / 3); 382 } 383 } 384 385 loc >>= 2; 386 } 387 } 388 } else { 389 for (int i = 0; i < 16; i += 8) { 390 for (int j = 0; j < 16; j += 8) { 391 if (is8x8 & 1) { 392 u0 = bytestream2_get_byte(&dgb); 393 v0 = bytestream2_get_byte(&dgb); 394 u1 = bytestream2_get_byte(&dgb); 395 v1 = bytestream2_get_byte(&dgb); 396 loc = bytestream2_get_le32(&dgb); 397 u0 = (u0 << 4) | (u0 & 0xF); 398 v0 = (v0 << 4) | (v0 & 0xF); 399 u1 = (u1 << 4) | (u1 & 0xF); 400 v1 = (v1 << 4) | (v1 & 0xF); 401 udif = u1 - u0; 402 vdif = v1 - v0; 403 404 for (int ii = 0; ii < 8; ii += 2) { 405 for (int jj = 0; jj < 8; jj += 2) { 406 for (int iii = 0; iii < 2; iii++) { 407 for (int jjj = 0; jjj < 2; jjj++) { 408 u[i + ii + iii][j + jj + jjj] = u0 + ((udif * (int)(loc & 3) + 2) / 3); 409 v[i + ii + iii][j + jj + jjj] = v0 + ((vdif * (int)(loc & 3) + 2) / 3); 410 } 411 } 412 413 loc >>= 2; 414 } 415 } 416 } else if (escape) { 417 for (int ii = 0; ii < 8; ii += 4) { 418 for (int jj = 0; jj < 8; jj += 4) { 419 u0 = bytestream2_get_byte(&dgb); 420 v0 = bytestream2_get_byte(&dgb); 421 u1 = bytestream2_get_byte(&dgb); 422 v1 = bytestream2_get_byte(&dgb); 423 loc = bytestream2_get_le32(&dgb); 424 u0 = (u0 << 4) | (u0 & 0xF); 425 v0 = (v0 << 4) | (v0 & 0xF); 426 u1 = (u1 << 4) | (u1 & 0xF); 427 v1 = (v1 << 4) | (v1 & 0xF); 428 udif = u1 - u0; 429 vdif = v1 - v0; 430 431 for (int iii = 0; iii < 4; iii++) { 432 for (int jjj = 0; jjj < 4; jjj++) { 433 u[i + ii + iii][j + jj + jjj] = u0 + ((udif * (int)(loc & 3) + 2) / 3); 434 v[i + ii + iii][j + jj + jjj] = v0 + ((vdif * (int)(loc & 3) + 2) / 3); 435 436 loc >>= 2; 437 } 438 } 439 } 440 } 441 } 442 443 is8x8 >>= 1; 444 } 445 } 446 } 447 448 for (int i = 0; i < 16; i++) { 449 for (int j = 0; j < 16; j++) { 450 dstu[x + i * ulinesize + j] = u[i][j]; 451 dstv[x + i * vlinesize + j] = v[i][j]; 452 } 453 } 454 } 455 456 dstu += 16 * ulinesize; 457 dstv += 16 * vlinesize; 458 } 459 460 return 0; 461} 462 463static int decode_frame(AVCodecContext *avctx, AVFrame *p, 464 int *got_frame, AVPacket *avpkt) 465{ 466 NotchLCContext *s = avctx->priv_data; 467 GetByteContext *gb = &s->gb; 468 PutByteContext *pb = &s->pb; 469 unsigned uncompressed_size; 470 int ret; 471 472 if (avpkt->size <= 40) 473 return AVERROR_INVALIDDATA; 474 475 bytestream2_init(gb, avpkt->data, avpkt->size); 476 477 if (bytestream2_get_le32(gb) != MKBETAG('N','L','C','1')) 478 return AVERROR_INVALIDDATA; 479 480 uncompressed_size = bytestream2_get_le32(gb); 481 s->compressed_size = bytestream2_get_le32(gb); 482 s->format = bytestream2_get_le32(gb); 483 484 if (s->format > 2) 485 return AVERROR_PATCHWELCOME; 486 487 if (s->format == 0) { 488 ret = ff_lzf_uncompress(gb, &s->lzf_buffer, &s->lzf_size); 489 if (ret < 0) 490 return ret; 491 492 if (uncompressed_size > s->lzf_size) 493 return AVERROR_INVALIDDATA; 494 495 bytestream2_init(gb, s->lzf_buffer, uncompressed_size); 496 } else if (s->format == 1) { 497 if (bytestream2_get_bytes_left(gb) < uncompressed_size / 255) 498 return AVERROR_INVALIDDATA; 499 500 av_fast_padded_malloc(&s->uncompressed_buffer, &s->uncompressed_size, 501 uncompressed_size); 502 if (!s->uncompressed_buffer) 503 return AVERROR(ENOMEM); 504 505 bytestream2_init_writer(pb, s->uncompressed_buffer, s->uncompressed_size); 506 507 ret = lz4_decompress(avctx, gb, pb); 508 if (ret != uncompressed_size) 509 return AVERROR_INVALIDDATA; 510 511 bytestream2_init(gb, s->uncompressed_buffer, uncompressed_size); 512 } 513 514 ret = decode_blocks(avctx, p, uncompressed_size); 515 if (ret < 0) 516 return ret; 517 518 p->pict_type = AV_PICTURE_TYPE_I; 519 p->key_frame = 1; 520 521 *got_frame = 1; 522 523 return avpkt->size; 524} 525 526static av_cold int decode_end(AVCodecContext *avctx) 527{ 528 NotchLCContext *s = avctx->priv_data; 529 530 av_freep(&s->uncompressed_buffer); 531 s->uncompressed_size = 0; 532 av_freep(&s->lzf_buffer); 533 s->lzf_size = 0; 534 535 return 0; 536} 537 538const FFCodec ff_notchlc_decoder = { 539 .p.name = "notchlc", 540 .p.long_name = NULL_IF_CONFIG_SMALL("NotchLC"), 541 .p.type = AVMEDIA_TYPE_VIDEO, 542 .p.id = AV_CODEC_ID_NOTCHLC, 543 .priv_data_size = sizeof(NotchLCContext), 544 .init = decode_init, 545 .close = decode_end, 546 FF_CODEC_DECODE_CB(decode_frame), 547 .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS, 548 .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, 549}; 550