1/* 2 * Dxtory decoder 3 * 4 * Copyright (c) 2011 Konstantin Shishkov 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 <inttypes.h> 24 25#include "libavutil/common.h" 26#include "libavutil/intreadwrite.h" 27 28#define BITSTREAM_READER_LE 29#include "avcodec.h" 30#include "bytestream.h" 31#include "codec_internal.h" 32#include "get_bits.h" 33#include "unary.h" 34#include "thread.h" 35 36static int64_t get_raw_size(enum AVPixelFormat fmt, int width, int height) 37{ 38 switch (fmt) { 39 case AV_PIX_FMT_RGB555LE: 40 case AV_PIX_FMT_RGB565LE: 41 return width * height * 2LL; 42 case AV_PIX_FMT_RGB24: 43 case AV_PIX_FMT_BGR24: 44 case AV_PIX_FMT_YUV444P: 45 return width * height * 3LL; 46 case AV_PIX_FMT_YUV420P: 47 return (int64_t)(width * height) + 2 * AV_CEIL_RSHIFT(width, 1) * AV_CEIL_RSHIFT(height, 1); 48 case AV_PIX_FMT_YUV410P: 49 return (int64_t)(width * height) + 2 * AV_CEIL_RSHIFT(width, 2) * AV_CEIL_RSHIFT(height, 2); 50 } 51 52 return 0; 53} 54 55static void do_vflip(AVCodecContext *avctx, AVFrame *pic, int vflip) 56{ 57 if (!vflip) 58 return; 59 60 switch (pic->format) { 61 case AV_PIX_FMT_YUV444P: 62 pic->data[1] += (avctx->height - 1) * pic->linesize[1]; 63 pic->linesize[1] = -pic->linesize[1]; 64 pic->data[2] += (avctx->height - 1) * pic->linesize[2]; 65 pic->linesize[2] = -pic->linesize[2]; 66 case AV_PIX_FMT_RGB555LE: 67 case AV_PIX_FMT_RGB565LE: 68 case AV_PIX_FMT_BGR24: 69 case AV_PIX_FMT_RGB24: 70 pic->data[0] += (avctx->height - 1) * pic->linesize[0]; 71 pic->linesize[0] = -pic->linesize[0]; 72 break; 73 case AV_PIX_FMT_YUV410P: 74 pic->data[0] += (avctx->height - 1) * pic->linesize[0]; 75 pic->linesize[0] = -pic->linesize[0]; 76 pic->data[1] += (AV_CEIL_RSHIFT(avctx->height, 2) - 1) * pic->linesize[1]; 77 pic->linesize[1] = -pic->linesize[1]; 78 pic->data[2] += (AV_CEIL_RSHIFT(avctx->height, 2) - 1) * pic->linesize[2]; 79 pic->linesize[2] = -pic->linesize[2]; 80 break; 81 case AV_PIX_FMT_YUV420P: 82 pic->data[0] += (avctx->height - 1) * pic->linesize[0]; 83 pic->linesize[0] = -pic->linesize[0]; 84 pic->data[1] += (AV_CEIL_RSHIFT(avctx->height, 1) - 1) * pic->linesize[1]; 85 pic->linesize[1] = -pic->linesize[1]; 86 pic->data[2] += (AV_CEIL_RSHIFT(avctx->height, 1) - 1) * pic->linesize[2]; 87 pic->linesize[2] = -pic->linesize[2]; 88 break; 89 } 90} 91 92static int dxtory_decode_v1_rgb(AVCodecContext *avctx, AVFrame *pic, 93 const uint8_t *src, int src_size, 94 int id, int bpp, uint32_t vflipped) 95{ 96 int h; 97 uint8_t *dst; 98 int ret; 99 100 if (src_size < get_raw_size(id, avctx->width, avctx->height)) { 101 av_log(avctx, AV_LOG_ERROR, "packet too small\n"); 102 return AVERROR_INVALIDDATA; 103 } 104 105 avctx->pix_fmt = id; 106 if ((ret = ff_thread_get_buffer(avctx, pic, 0)) < 0) 107 return ret; 108 109 do_vflip(avctx, pic, vflipped); 110 111 dst = pic->data[0]; 112 for (h = 0; h < avctx->height; h++) { 113 memcpy(dst, src, avctx->width * bpp); 114 src += avctx->width * bpp; 115 dst += pic->linesize[0]; 116 } 117 118 do_vflip(avctx, pic, vflipped); 119 120 return 0; 121} 122 123static int dxtory_decode_v1_410(AVCodecContext *avctx, AVFrame *pic, 124 const uint8_t *src, int src_size, 125 uint32_t vflipped) 126{ 127 int h, w; 128 uint8_t *Y1, *Y2, *Y3, *Y4, *U, *V; 129 int height, width, hmargin, vmargin; 130 int huvborder; 131 int ret; 132 133 if (src_size < get_raw_size(AV_PIX_FMT_YUV410P, avctx->width, avctx->height)) { 134 av_log(avctx, AV_LOG_ERROR, "packet too small\n"); 135 return AVERROR_INVALIDDATA; 136 } 137 138 avctx->pix_fmt = AV_PIX_FMT_YUV410P; 139 if ((ret = ff_thread_get_buffer(avctx, pic, 0)) < 0) 140 return ret; 141 142 do_vflip(avctx, pic, vflipped); 143 144 height = avctx->height & ~3; 145 width = avctx->width & ~3; 146 hmargin = avctx->width - width; 147 vmargin = avctx->height - height; 148 huvborder = AV_CEIL_RSHIFT(avctx->width, 2) - 1; 149 150 Y1 = pic->data[0]; 151 Y2 = pic->data[0] + pic->linesize[0]; 152 Y3 = pic->data[0] + pic->linesize[0] * 2; 153 Y4 = pic->data[0] + pic->linesize[0] * 3; 154 U = pic->data[1]; 155 V = pic->data[2]; 156 for (h = 0; h < height; h += 4) { 157 for (w = 0; w < width; w += 4) { 158 AV_COPY32U(Y1 + w, src); 159 AV_COPY32U(Y2 + w, src + 4); 160 AV_COPY32U(Y3 + w, src + 8); 161 AV_COPY32U(Y4 + w, src + 12); 162 U[w >> 2] = src[16] + 0x80; 163 V[w >> 2] = src[17] + 0x80; 164 src += 18; 165 } 166 if (hmargin) { 167 for (w = 0; w < hmargin; w++) { 168 Y1[width + w] = src[w]; 169 Y2[width + w] = src[w + hmargin * 1]; 170 Y3[width + w] = src[w + hmargin * 2]; 171 Y4[width + w] = src[w + hmargin * 3]; 172 } 173 src += 4 * hmargin; 174 U[huvborder] = src[0] + 0x80; 175 V[huvborder] = src[1] + 0x80; 176 src += 2; 177 } 178 Y1 += pic->linesize[0] * 4; 179 Y2 += pic->linesize[0] * 4; 180 Y3 += pic->linesize[0] * 4; 181 Y4 += pic->linesize[0] * 4; 182 U += pic->linesize[1]; 183 V += pic->linesize[2]; 184 } 185 186 if (vmargin) { 187 for (w = 0; w < width; w += 4) { 188 AV_COPY32U(Y1 + w, src); 189 if (vmargin > 1) 190 AV_COPY32U(Y2 + w, src + 4); 191 if (vmargin > 2) 192 AV_COPY32U(Y3 + w, src + 8); 193 src += 4 * vmargin; 194 U[w >> 2] = src[0] + 0x80; 195 V[w >> 2] = src[1] + 0x80; 196 src += 2; 197 } 198 if (hmargin) { 199 for (w = 0; w < hmargin; w++) { 200 AV_COPY32U(Y1 + w, src); 201 if (vmargin > 1) 202 AV_COPY32U(Y2 + w, src + 4); 203 if (vmargin > 2) 204 AV_COPY32U(Y3 + w, src + 8); 205 src += 4 * vmargin; 206 } 207 U[huvborder] = src[0] + 0x80; 208 V[huvborder] = src[1] + 0x80; 209 src += 2; 210 } 211 } 212 213 do_vflip(avctx, pic, vflipped); 214 215 return 0; 216} 217 218static int dxtory_decode_v1_420(AVCodecContext *avctx, AVFrame *pic, 219 const uint8_t *src, int src_size, 220 uint32_t vflipped) 221{ 222 int h, w; 223 uint8_t *Y1, *Y2, *U, *V; 224 int height, width, hmargin, vmargin; 225 int huvborder; 226 int ret; 227 228 if (src_size < get_raw_size(AV_PIX_FMT_YUV420P, avctx->width, avctx->height)) { 229 av_log(avctx, AV_LOG_ERROR, "packet too small\n"); 230 return AVERROR_INVALIDDATA; 231 } 232 233 avctx->pix_fmt = AV_PIX_FMT_YUV420P; 234 if ((ret = ff_thread_get_buffer(avctx, pic, 0)) < 0) 235 return ret; 236 237 do_vflip(avctx, pic, vflipped); 238 239 height = avctx->height & ~1; 240 width = avctx->width & ~1; 241 hmargin = avctx->width - width; 242 vmargin = avctx->height - height; 243 huvborder = AV_CEIL_RSHIFT(avctx->width, 1) - 1; 244 245 Y1 = pic->data[0]; 246 Y2 = pic->data[0] + pic->linesize[0]; 247 U = pic->data[1]; 248 V = pic->data[2]; 249 for (h = 0; h < height; h += 2) { 250 for (w = 0; w < width; w += 2) { 251 AV_COPY16(Y1 + w, src); 252 AV_COPY16(Y2 + w, src + 2); 253 U[w >> 1] = src[4] + 0x80; 254 V[w >> 1] = src[5] + 0x80; 255 src += 6; 256 } 257 if (hmargin) { 258 Y1[width + 1] = src[0]; 259 Y2[width + 1] = src[1]; 260 U[huvborder] = src[2] + 0x80; 261 V[huvborder] = src[3] + 0x80; 262 src += 4; 263 } 264 Y1 += pic->linesize[0] * 2; 265 Y2 += pic->linesize[0] * 2; 266 U += pic->linesize[1]; 267 V += pic->linesize[2]; 268 } 269 270 if (vmargin) { 271 for (w = 0; w < width; w += 2) { 272 AV_COPY16U(Y1 + w, src); 273 U[w >> 1] = src[0] + 0x80; 274 V[w >> 1] = src[1] + 0x80; 275 src += 4; 276 } 277 if (hmargin) { 278 Y1[w] = src[0]; 279 U[huvborder] = src[1] + 0x80; 280 V[huvborder] = src[2] + 0x80; 281 src += 3; 282 } 283 } 284 285 do_vflip(avctx, pic, vflipped); 286 287 return 0; 288} 289 290static int dxtory_decode_v1_444(AVCodecContext *avctx, AVFrame *pic, 291 const uint8_t *src, int src_size, 292 uint32_t vflipped) 293{ 294 int h, w; 295 uint8_t *Y, *U, *V; 296 int ret; 297 298 if (src_size < get_raw_size(AV_PIX_FMT_YUV444P, avctx->width, avctx->height)) { 299 av_log(avctx, AV_LOG_ERROR, "packet too small\n"); 300 return AVERROR_INVALIDDATA; 301 } 302 303 avctx->pix_fmt = AV_PIX_FMT_YUV444P; 304 if ((ret = ff_thread_get_buffer(avctx, pic, 0)) < 0) 305 return ret; 306 307 do_vflip(avctx, pic, vflipped); 308 309 Y = pic->data[0]; 310 U = pic->data[1]; 311 V = pic->data[2]; 312 for (h = 0; h < avctx->height; h++) { 313 for (w = 0; w < avctx->width; w++) { 314 Y[w] = *src++; 315 U[w] = *src++ ^ 0x80; 316 V[w] = *src++ ^ 0x80; 317 } 318 Y += pic->linesize[0]; 319 U += pic->linesize[1]; 320 V += pic->linesize[2]; 321 } 322 323 do_vflip(avctx, pic, vflipped); 324 325 return 0; 326} 327 328static const uint8_t def_lru[8] = { 0x00, 0x20, 0x40, 0x60, 0x80, 0xA0, 0xC0, 0xFF }; 329static const uint8_t def_lru_555[8] = { 0x00, 0x08, 0x10, 0x18, 0x1F }; 330static const uint8_t def_lru_565[8] = { 0x00, 0x08, 0x10, 0x20, 0x30, 0x3F }; 331 332static inline uint8_t decode_sym(GetBitContext *gb, uint8_t lru[8]) 333{ 334 uint8_t c, val; 335 336 c = get_unary(gb, 0, 8); 337 if (!c) { 338 val = get_bits(gb, 8); 339 memmove(lru + 1, lru, sizeof(*lru) * (8 - 1)); 340 } else { 341 val = lru[c - 1]; 342 memmove(lru + 1, lru, sizeof(*lru) * (c - 1)); 343 } 344 lru[0] = val; 345 346 return val; 347} 348 349static int check_slice_size(AVCodecContext *avctx, 350 const uint8_t *src, int src_size, 351 int slice_size, int off) 352{ 353 int cur_slice_size; 354 355 if (slice_size > src_size - off) { 356 av_log(avctx, AV_LOG_ERROR, 357 "invalid slice size %d (only %d bytes left)\n", 358 slice_size, src_size - off); 359 return AVERROR_INVALIDDATA; 360 } 361 if (slice_size <= 16) { 362 av_log(avctx, AV_LOG_ERROR, "invalid slice size %d\n", 363 slice_size); 364 return AVERROR_INVALIDDATA; 365 } 366 367 cur_slice_size = AV_RL32(src + off); 368 if (cur_slice_size != slice_size - 16) { 369 av_log(avctx, AV_LOG_ERROR, 370 "Slice sizes mismatch: got %d instead of %d\n", 371 cur_slice_size, slice_size - 16); 372 } 373 374 return 0; 375} 376 377static int load_buffer(AVCodecContext *avctx, 378 const uint8_t *src, int src_size, 379 GetByteContext *gb, 380 int *nslices, int *off) 381{ 382 bytestream2_init(gb, src, src_size); 383 *nslices = bytestream2_get_le16(gb); 384 *off = FFALIGN(*nslices * 4 + 2, 16); 385 if (src_size < *off) { 386 av_log(avctx, AV_LOG_ERROR, "no slice data\n"); 387 return AVERROR_INVALIDDATA; 388 } 389 390 if (!*nslices) { 391 avpriv_request_sample(avctx, "%d slices for %dx%d", *nslices, 392 avctx->width, avctx->height); 393 return AVERROR_PATCHWELCOME; 394 } 395 396 return 0; 397} 398 399static inline uint8_t decode_sym_565(GetBitContext *gb, uint8_t lru[8], 400 int bits) 401{ 402 uint8_t c, val; 403 404 c = get_unary(gb, 0, bits); 405 if (!c) { 406 val = get_bits(gb, bits); 407 memmove(lru + 1, lru, sizeof(*lru) * (6 - 1)); 408 } else { 409 val = lru[c - 1]; 410 memmove(lru + 1, lru, sizeof(*lru) * (c - 1)); 411 } 412 lru[0] = val; 413 414 return val; 415} 416 417typedef int (*decode_slice_func)(GetBitContext *gb, AVFrame *frame, 418 int line, int height, uint8_t lru[3][8]); 419 420typedef void (*setup_lru_func)(uint8_t lru[3][8]); 421 422static int dxtory_decode_v2(AVCodecContext *avctx, AVFrame *pic, 423 const uint8_t *src, int src_size, 424 decode_slice_func decode_slice, 425 setup_lru_func setup_lru, 426 enum AVPixelFormat fmt, 427 uint32_t vflipped) 428{ 429 GetByteContext gb, gb_check; 430 GetBitContext gb2; 431 int nslices, slice, line = 0; 432 uint32_t off, slice_size; 433 uint64_t off_check; 434 uint8_t lru[3][8]; 435 int ret; 436 437 ret = load_buffer(avctx, src, src_size, &gb, &nslices, &off); 438 if (ret < 0) 439 return ret; 440 441 off_check = off; 442 gb_check = gb; 443 for (slice = 0; slice < nslices; slice++) { 444 slice_size = bytestream2_get_le32(&gb_check); 445 446 if (slice_size <= 16 + (avctx->height * avctx->width / (8 * nslices))) 447 return AVERROR_INVALIDDATA; 448 off_check += slice_size; 449 } 450 451 if (off_check - avctx->discard_damaged_percentage*off_check/100 > src_size) 452 return AVERROR_INVALIDDATA; 453 454 avctx->pix_fmt = fmt; 455 if ((ret = ff_thread_get_buffer(avctx, pic, 0)) < 0) 456 return ret; 457 458 do_vflip(avctx, pic, vflipped); 459 460 for (slice = 0; slice < nslices; slice++) { 461 slice_size = bytestream2_get_le32(&gb); 462 463 setup_lru(lru); 464 465 ret = check_slice_size(avctx, src, src_size, slice_size, off); 466 if (ret < 0) 467 return ret; 468 469 if ((ret = init_get_bits8(&gb2, src + off + 16, slice_size - 16)) < 0) 470 return ret; 471 472 line += decode_slice(&gb2, pic, line, avctx->height - line, lru); 473 474 off += slice_size; 475 } 476 477 if (avctx->height - line) { 478 avpriv_request_sample(avctx, "Not enough slice data available"); 479 } 480 481 do_vflip(avctx, pic, vflipped); 482 483 return 0; 484} 485 486av_always_inline 487static int dx2_decode_slice_5x5(GetBitContext *gb, AVFrame *frame, 488 int line, int left, uint8_t lru[3][8], 489 int is_565) 490{ 491 int x, y; 492 int r, g, b; 493 int width = frame->width; 494 int stride = frame->linesize[0]; 495 uint8_t *dst = frame->data[0] + stride * line; 496 497 for (y = 0; y < left && get_bits_left(gb) >= 3 * width; y++) { 498 for (x = 0; x < width; x++) { 499 b = decode_sym_565(gb, lru[0], 5); 500 g = decode_sym_565(gb, lru[1], is_565 ? 6 : 5); 501 r = decode_sym_565(gb, lru[2], 5); 502 dst[x * 3 + 0] = (r << 3) | (r >> 2); 503 dst[x * 3 + 1] = is_565 ? (g << 2) | (g >> 4) : (g << 3) | (g >> 2); 504 dst[x * 3 + 2] = (b << 3) | (b >> 2); 505 } 506 507 dst += stride; 508 } 509 510 return y; 511} 512 513static void setup_lru_555(uint8_t lru[3][8]) 514{ 515 memcpy(lru[0], def_lru_555, 8 * sizeof(*def_lru)); 516 memcpy(lru[1], def_lru_555, 8 * sizeof(*def_lru)); 517 memcpy(lru[2], def_lru_555, 8 * sizeof(*def_lru)); 518} 519 520static void setup_lru_565(uint8_t lru[3][8]) 521{ 522 memcpy(lru[0], def_lru_555, 8 * sizeof(*def_lru)); 523 memcpy(lru[1], def_lru_565, 8 * sizeof(*def_lru)); 524 memcpy(lru[2], def_lru_555, 8 * sizeof(*def_lru)); 525} 526 527static int dx2_decode_slice_555(GetBitContext *gb, AVFrame *frame, 528 int line, int left, uint8_t lru[3][8]) 529{ 530 return dx2_decode_slice_5x5(gb, frame, line, left, lru, 0); 531} 532 533static int dx2_decode_slice_565(GetBitContext *gb, AVFrame *frame, 534 int line, int left, uint8_t lru[3][8]) 535{ 536 return dx2_decode_slice_5x5(gb, frame, line, left, lru, 1); 537} 538 539static int dxtory_decode_v2_565(AVCodecContext *avctx, AVFrame *pic, 540 const uint8_t *src, int src_size, int is_565, 541 uint32_t vflipped) 542{ 543 enum AVPixelFormat fmt = AV_PIX_FMT_RGB24; 544 if (is_565) 545 return dxtory_decode_v2(avctx, pic, src, src_size, 546 dx2_decode_slice_565, 547 setup_lru_565, 548 fmt, vflipped); 549 else 550 return dxtory_decode_v2(avctx, pic, src, src_size, 551 dx2_decode_slice_555, 552 setup_lru_555, 553 fmt, vflipped); 554} 555 556static int dx2_decode_slice_rgb(GetBitContext *gb, AVFrame *frame, 557 int line, int left, uint8_t lru[3][8]) 558{ 559 int x, y; 560 int width = frame->width; 561 int stride = frame->linesize[0]; 562 uint8_t *dst = frame->data[0] + stride * line; 563 564 for (y = 0; y < left && get_bits_left(gb) >= 3 * width; y++) { 565 for (x = 0; x < width; x++) { 566 dst[x * 3 + 0] = decode_sym(gb, lru[0]); 567 dst[x * 3 + 1] = decode_sym(gb, lru[1]); 568 dst[x * 3 + 2] = decode_sym(gb, lru[2]); 569 } 570 571 dst += stride; 572 } 573 574 return y; 575} 576 577static void default_setup_lru(uint8_t lru[3][8]) 578{ 579 int i; 580 581 for (i = 0; i < 3; i++) 582 memcpy(lru[i], def_lru, 8 * sizeof(*def_lru)); 583} 584 585static int dxtory_decode_v2_rgb(AVCodecContext *avctx, AVFrame *pic, 586 const uint8_t *src, int src_size, 587 uint32_t vflipped) 588{ 589 return dxtory_decode_v2(avctx, pic, src, src_size, 590 dx2_decode_slice_rgb, 591 default_setup_lru, 592 AV_PIX_FMT_BGR24, vflipped); 593} 594 595static int dx2_decode_slice_410(GetBitContext *gb, AVFrame *frame, 596 int line, int left, 597 uint8_t lru[3][8]) 598{ 599 int x, y, i, j; 600 int width = frame->width; 601 602 int ystride = frame->linesize[0]; 603 int ustride = frame->linesize[1]; 604 int vstride = frame->linesize[2]; 605 606 uint8_t *Y = frame->data[0] + ystride * line; 607 uint8_t *U = frame->data[1] + (ustride >> 2) * line; 608 uint8_t *V = frame->data[2] + (vstride >> 2) * line; 609 610 int h, w, hmargin, vmargin; 611 int huvborder; 612 613 h = frame->height & ~3; 614 w = frame->width & ~3; 615 hmargin = frame->width - w; 616 vmargin = frame->height - h; 617 huvborder = AV_CEIL_RSHIFT(frame->width, 2) - 1; 618 619 for (y = 0; y < left - 3 && get_bits_left(gb) >= 18 * w / 4 + hmargin * 4 + (!!hmargin * 2); y += 4) { 620 for (x = 0; x < w; x += 4) { 621 for (j = 0; j < 4; j++) 622 for (i = 0; i < 4; i++) 623 Y[x + i + j * ystride] = decode_sym(gb, lru[0]); 624 U[x >> 2] = decode_sym(gb, lru[1]) ^ 0x80; 625 V[x >> 2] = decode_sym(gb, lru[2]) ^ 0x80; 626 } 627 if (hmargin) { 628 for (j = 0; j < 4; j++) 629 for (i = 0; i < hmargin; i++) 630 Y[x + i + j * ystride] = decode_sym(gb, lru[0]); 631 U[huvborder] = decode_sym(gb, lru[1]) ^ 0x80; 632 V[huvborder] = decode_sym(gb, lru[2]) ^ 0x80; 633 } 634 635 Y += ystride * 4; 636 U += ustride; 637 V += vstride; 638 } 639 640 if (vmargin && y + vmargin == left) { 641 for (x = 0; x < width; x += 4) { 642 for (j = 0; j < vmargin; j++) 643 for (i = 0; i < 4; i++) 644 Y[x + i + j * ystride] = decode_sym(gb, lru[0]); 645 U[x >> 2] = decode_sym(gb, lru[1]) ^ 0x80; 646 V[x >> 2] = decode_sym(gb, lru[2]) ^ 0x80; 647 } 648 if (hmargin) { 649 for (j = 0; j < vmargin; j++) { 650 for (i = 0; i < hmargin; i++) 651 Y[x + i + j * ystride] = decode_sym(gb, lru[0]); 652 } 653 U[huvborder] = decode_sym(gb, lru[1]) ^ 0x80; 654 V[huvborder] = decode_sym(gb, lru[2]) ^ 0x80; 655 } 656 657 y += vmargin; 658 } 659 660 return y; 661} 662 663 664static int dxtory_decode_v2_410(AVCodecContext *avctx, AVFrame *pic, 665 const uint8_t *src, int src_size, 666 uint32_t vflipped) 667{ 668 return dxtory_decode_v2(avctx, pic, src, src_size, 669 dx2_decode_slice_410, 670 default_setup_lru, 671 AV_PIX_FMT_YUV410P, vflipped); 672} 673 674static int dx2_decode_slice_420(GetBitContext *gb, AVFrame *frame, 675 int line, int left, 676 uint8_t lru[3][8]) 677{ 678 int x, y; 679 680 int width = frame->width; 681 682 int ystride = frame->linesize[0]; 683 int ustride = frame->linesize[1]; 684 int vstride = frame->linesize[2]; 685 686 uint8_t *Y = frame->data[0] + ystride * line; 687 uint8_t *U = frame->data[1] + (ustride >> 1) * line; 688 uint8_t *V = frame->data[2] + (vstride >> 1) * line; 689 690 int h, w, hmargin, vmargin; 691 int huvborder; 692 693 h = frame->height & ~1; 694 w = frame->width & ~1; 695 hmargin = frame->width - w; 696 vmargin = frame->height - h; 697 huvborder = AV_CEIL_RSHIFT(frame->width, 1) - 1; 698 699 for (y = 0; y < left - 1 && get_bits_left(gb) >= 3 * w + hmargin * 4; y += 2) { 700 for (x = 0; x < w; x += 2) { 701 Y[x + 0 + 0 * ystride] = decode_sym(gb, lru[0]); 702 Y[x + 1 + 0 * ystride] = decode_sym(gb, lru[0]); 703 Y[x + 0 + 1 * ystride] = decode_sym(gb, lru[0]); 704 Y[x + 1 + 1 * ystride] = decode_sym(gb, lru[0]); 705 U[x >> 1] = decode_sym(gb, lru[1]) ^ 0x80; 706 V[x >> 1] = decode_sym(gb, lru[2]) ^ 0x80; 707 } 708 if (hmargin) { 709 Y[x + 0 * ystride] = decode_sym(gb, lru[0]); 710 Y[x + 1 * ystride] = decode_sym(gb, lru[0]); 711 U[huvborder] = decode_sym(gb, lru[1]) ^ 0x80; 712 V[huvborder] = decode_sym(gb, lru[2]) ^ 0x80; 713 } 714 715 Y += ystride * 2; 716 U += ustride; 717 V += vstride; 718 } 719 720 if (vmargin) { 721 for (x = 0; x < width; x += 2) { 722 Y[x + 0] = decode_sym(gb, lru[0]); 723 U[x >> 1] = decode_sym(gb, lru[1]) ^ 0x80; 724 V[x >> 1] = decode_sym(gb, lru[2]) ^ 0x80; 725 } 726 if (hmargin) { 727 Y[x] = decode_sym(gb, lru[0]); 728 U[huvborder] = decode_sym(gb, lru[1]) ^ 0x80; 729 V[huvborder] = decode_sym(gb, lru[2]) ^ 0x80; 730 } 731 } 732 733 return y; 734} 735 736static int dxtory_decode_v2_420(AVCodecContext *avctx, AVFrame *pic, 737 const uint8_t *src, int src_size, 738 uint32_t vflipped) 739{ 740 return dxtory_decode_v2(avctx, pic, src, src_size, 741 dx2_decode_slice_420, 742 default_setup_lru, 743 AV_PIX_FMT_YUV420P, vflipped); 744} 745 746static int dx2_decode_slice_444(GetBitContext *gb, AVFrame *frame, 747 int line, int left, 748 uint8_t lru[3][8]) 749{ 750 int x, y; 751 752 int width = frame->width; 753 754 int ystride = frame->linesize[0]; 755 int ustride = frame->linesize[1]; 756 int vstride = frame->linesize[2]; 757 758 uint8_t *Y = frame->data[0] + ystride * line; 759 uint8_t *U = frame->data[1] + ustride * line; 760 uint8_t *V = frame->data[2] + vstride * line; 761 762 for (y = 0; y < left && get_bits_left(gb) >= 3 * width; y++) { 763 for (x = 0; x < width; x++) { 764 Y[x] = decode_sym(gb, lru[0]); 765 U[x] = decode_sym(gb, lru[1]) ^ 0x80; 766 V[x] = decode_sym(gb, lru[2]) ^ 0x80; 767 } 768 769 Y += ystride; 770 U += ustride; 771 V += vstride; 772 } 773 774 return y; 775} 776 777static int dxtory_decode_v2_444(AVCodecContext *avctx, AVFrame *pic, 778 const uint8_t *src, int src_size, 779 uint32_t vflipped) 780{ 781 return dxtory_decode_v2(avctx, pic, src, src_size, 782 dx2_decode_slice_444, 783 default_setup_lru, 784 AV_PIX_FMT_YUV444P, vflipped); 785} 786 787static int decode_frame(AVCodecContext *avctx, AVFrame *pic, 788 int *got_frame, AVPacket *avpkt) 789{ 790 const uint8_t *src = avpkt->data; 791 uint32_t type; 792 int vflipped, ret; 793 794 if (avpkt->size < 16) { 795 av_log(avctx, AV_LOG_ERROR, "packet too small\n"); 796 return AVERROR_INVALIDDATA; 797 } 798 799 type = AV_RB32(src); 800 vflipped = !!(type & 0x20); 801 802 switch (type) { 803 case 0x01000021: 804 case 0x01000001: 805 ret = dxtory_decode_v1_rgb(avctx, pic, src + 16, avpkt->size - 16, 806 AV_PIX_FMT_BGR24, 3, vflipped); 807 break; 808 case 0x01000029: 809 case 0x01000009: 810 ret = dxtory_decode_v2_rgb(avctx, pic, src + 16, avpkt->size - 16, vflipped); 811 break; 812 case 0x02000021: 813 case 0x02000001: 814 ret = dxtory_decode_v1_420(avctx, pic, src + 16, avpkt->size - 16, vflipped); 815 break; 816 case 0x02000029: 817 case 0x02000009: 818 ret = dxtory_decode_v2_420(avctx, pic, src + 16, avpkt->size - 16, vflipped); 819 break; 820 case 0x03000021: 821 case 0x03000001: 822 ret = dxtory_decode_v1_410(avctx, pic, src + 16, avpkt->size - 16, vflipped); 823 break; 824 case 0x03000029: 825 case 0x03000009: 826 ret = dxtory_decode_v2_410(avctx, pic, src + 16, avpkt->size - 16, vflipped); 827 break; 828 case 0x04000021: 829 case 0x04000001: 830 ret = dxtory_decode_v1_444(avctx, pic, src + 16, avpkt->size - 16, vflipped); 831 break; 832 case 0x04000029: 833 case 0x04000009: 834 ret = dxtory_decode_v2_444(avctx, pic, src + 16, avpkt->size - 16, vflipped); 835 break; 836 case 0x17000021: 837 case 0x17000001: 838 ret = dxtory_decode_v1_rgb(avctx, pic, src + 16, avpkt->size - 16, 839 AV_PIX_FMT_RGB565LE, 2, vflipped); 840 break; 841 case 0x17000029: 842 case 0x17000009: 843 ret = dxtory_decode_v2_565(avctx, pic, src + 16, avpkt->size - 16, 1, vflipped); 844 break; 845 case 0x18000021: 846 case 0x19000021: 847 case 0x18000001: 848 case 0x19000001: 849 ret = dxtory_decode_v1_rgb(avctx, pic, src + 16, avpkt->size - 16, 850 AV_PIX_FMT_RGB555LE, 2, vflipped); 851 break; 852 case 0x18000029: 853 case 0x19000029: 854 case 0x18000009: 855 case 0x19000009: 856 ret = dxtory_decode_v2_565(avctx, pic, src + 16, avpkt->size - 16, 0, vflipped); 857 break; 858 default: 859 avpriv_request_sample(avctx, "Frame header %"PRIX32, type); 860 return AVERROR_PATCHWELCOME; 861 } 862 863 if (ret) 864 return ret; 865 866 pic->pict_type = AV_PICTURE_TYPE_I; 867 pic->key_frame = 1; 868 *got_frame = 1; 869 870 return avpkt->size; 871} 872 873const FFCodec ff_dxtory_decoder = { 874 .p.name = "dxtory", 875 .p.long_name = NULL_IF_CONFIG_SMALL("Dxtory"), 876 .p.type = AVMEDIA_TYPE_VIDEO, 877 .p.id = AV_CODEC_ID_DXTORY, 878 FF_CODEC_DECODE_CB(decode_frame), 879 .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS, 880}; 881