Mercurial > libavcodec.hg
comparison lcldec.c @ 9749:4a4192578b60 libavcodec
Make lcldec produce YUV output when the input file is coded like that, instead
of having it do its own inefficient fixed-point YUV to RGB conversion.
author | reimar |
---|---|
date | Sun, 31 May 2009 09:09:32 +0000 |
parents | d5929e456b07 |
children | a87706453840 |
comparison
equal
deleted
inserted
replaced
9748:77920505b11d | 9749:4a4192578b60 |
---|---|
67 unsigned char* decomp_buf; | 67 unsigned char* decomp_buf; |
68 #if CONFIG_ZLIB | 68 #if CONFIG_ZLIB |
69 z_stream zstream; | 69 z_stream zstream; |
70 #endif | 70 #endif |
71 } LclDecContext; | 71 } LclDecContext; |
72 | |
73 | |
74 /* | |
75 * | |
76 * Helper functions | |
77 * | |
78 */ | |
79 static inline unsigned char fix (int pix14) | |
80 { | |
81 int tmp; | |
82 | |
83 tmp = (pix14 + 0x80000) >> 20; | |
84 return av_clip_uint8(tmp); | |
85 } | |
86 | |
87 | |
88 | |
89 static inline unsigned char get_b (unsigned char yq, signed char bq) | |
90 { | |
91 return fix((yq << 20) + bq * 1858076); | |
92 } | |
93 | |
94 | |
95 | |
96 static inline unsigned char get_g (unsigned char yq, signed char bq, signed char rq) | |
97 { | |
98 return fix((yq << 20) - bq * 360857 - rq * 748830); | |
99 } | |
100 | |
101 | |
102 | |
103 static inline unsigned char get_r (unsigned char yq, signed char rq) | |
104 { | |
105 return fix((yq << 20) + rq * 1470103); | |
106 } | |
107 | |
108 | 72 |
109 | 73 |
110 static unsigned int mszh_decomp(unsigned char * srcptr, int srclen, unsigned char * destptr, unsigned int destsize) | 74 static unsigned int mszh_decomp(unsigned char * srcptr, int srclen, unsigned char * destptr, unsigned int destsize) |
111 { | 75 { |
112 unsigned char *destptr_bak = destptr; | 76 unsigned char *destptr_bak = destptr; |
164 LclDecContext * const c = avctx->priv_data; | 128 LclDecContext * const c = avctx->priv_data; |
165 unsigned char *encoded = (unsigned char *)buf; | 129 unsigned char *encoded = (unsigned char *)buf; |
166 unsigned int pixel_ptr; | 130 unsigned int pixel_ptr; |
167 int row, col; | 131 int row, col; |
168 unsigned char *outptr; | 132 unsigned char *outptr; |
133 uint8_t *y_out, *u_out, *v_out; | |
169 unsigned int width = avctx->width; // Real image width | 134 unsigned int width = avctx->width; // Real image width |
170 unsigned int height = avctx->height; // Real image height | 135 unsigned int height = avctx->height; // Real image height |
171 unsigned int mszh_dlen; | 136 unsigned int mszh_dlen; |
172 unsigned char yq, y1q, uq, vq; | 137 unsigned char yq, y1q, uq, vq; |
173 int uqvq; | 138 int uqvq; |
395 return -1; | 360 return -1; |
396 } | 361 } |
397 } | 362 } |
398 | 363 |
399 /* Convert colorspace */ | 364 /* Convert colorspace */ |
365 y_out = c->pic.data[0] + (height - 1) * c->pic.linesize[0]; | |
366 u_out = c->pic.data[1] + (height - 1) * c->pic.linesize[1]; | |
367 v_out = c->pic.data[2] + (height - 1) * c->pic.linesize[2]; | |
400 switch (c->imgtype) { | 368 switch (c->imgtype) { |
401 case IMGTYPE_YUV111: | 369 case IMGTYPE_YUV111: |
402 for (row = height - 1; row >= 0; row--) { | 370 for (row = 0; row < height; row++) { |
403 pixel_ptr = row * c->pic.linesize[0]; | |
404 for (col = 0; col < width; col++) { | 371 for (col = 0; col < width; col++) { |
405 outptr[pixel_ptr++] = get_b(encoded[0], encoded[1]); | 372 y_out[col] = *encoded++; |
406 outptr[pixel_ptr++] = get_g(encoded[0], encoded[1], encoded[2]); | 373 u_out[col] = *encoded++ + 128; |
407 outptr[pixel_ptr++] = get_r(encoded[0], encoded[2]); | 374 v_out[col] = *encoded++ + 128; |
408 encoded += 3; | 375 } |
409 } | 376 y_out -= c->pic.linesize[0]; |
377 u_out -= c->pic.linesize[1]; | |
378 v_out -= c->pic.linesize[2]; | |
410 } | 379 } |
411 break; | 380 break; |
412 case IMGTYPE_YUV422: | 381 case IMGTYPE_YUV422: |
413 for (row = height - 1; row >= 0; row--) { | 382 for (row = 0; row < height; row++) { |
414 pixel_ptr = row * c->pic.linesize[0]; | 383 for (col = 0; col < width - 3; col += 4) { |
415 for (col = 0; col < width/4; col++) { | 384 memcpy(y_out + col, encoded, 4); |
416 outptr[pixel_ptr++] = get_b(encoded[0], encoded[4]); | 385 encoded += 4; |
417 outptr[pixel_ptr++] = get_g(encoded[0], encoded[4], encoded[6]); | 386 u_out[ col >> 1 ] = *encoded++ + 128; |
418 outptr[pixel_ptr++] = get_r(encoded[0], encoded[6]); | 387 u_out[(col >> 1) + 1] = *encoded++ + 128; |
419 outptr[pixel_ptr++] = get_b(encoded[1], encoded[4]); | 388 v_out[ col >> 1 ] = *encoded++ + 128; |
420 outptr[pixel_ptr++] = get_g(encoded[1], encoded[4], encoded[6]); | 389 v_out[(col >> 1) + 1] = *encoded++ + 128; |
421 outptr[pixel_ptr++] = get_r(encoded[1], encoded[6]); | 390 } |
422 outptr[pixel_ptr++] = get_b(encoded[2], encoded[5]); | 391 y_out -= c->pic.linesize[0]; |
423 outptr[pixel_ptr++] = get_g(encoded[2], encoded[5], encoded[7]); | 392 u_out -= c->pic.linesize[1]; |
424 outptr[pixel_ptr++] = get_r(encoded[2], encoded[7]); | 393 v_out -= c->pic.linesize[2]; |
425 outptr[pixel_ptr++] = get_b(encoded[3], encoded[5]); | |
426 outptr[pixel_ptr++] = get_g(encoded[3], encoded[5], encoded[7]); | |
427 outptr[pixel_ptr++] = get_r(encoded[3], encoded[7]); | |
428 encoded += 8; | |
429 } | |
430 } | 394 } |
431 break; | 395 break; |
432 case IMGTYPE_RGB24: | 396 case IMGTYPE_RGB24: |
433 for (row = height - 1; row >= 0; row--) { | 397 for (row = height - 1; row >= 0; row--) { |
434 pixel_ptr = row * c->pic.linesize[0]; | 398 pixel_ptr = row * c->pic.linesize[0]; |
435 memcpy(outptr + pixel_ptr, encoded, 3 * width); | 399 memcpy(outptr + pixel_ptr, encoded, 3 * width); |
436 encoded += 3 * width; | 400 encoded += 3 * width; |
437 } | 401 } |
438 break; | 402 break; |
439 case IMGTYPE_YUV411: | 403 case IMGTYPE_YUV411: |
440 for (row = height - 1; row >= 0; row--) { | 404 for (row = 0; row < height; row++) { |
441 pixel_ptr = row * c->pic.linesize[0]; | 405 for (col = 0; col < width - 3; col += 4) { |
442 for (col = 0; col < width/4; col++) { | 406 memcpy(y_out + col, encoded, 4); |
443 outptr[pixel_ptr++] = get_b(encoded[0], encoded[4]); | 407 encoded += 4; |
444 outptr[pixel_ptr++] = get_g(encoded[0], encoded[4], encoded[5]); | 408 u_out[col >> 2] = *encoded++ + 128; |
445 outptr[pixel_ptr++] = get_r(encoded[0], encoded[5]); | 409 v_out[col >> 2] = *encoded++ + 128; |
446 outptr[pixel_ptr++] = get_b(encoded[1], encoded[4]); | 410 } |
447 outptr[pixel_ptr++] = get_g(encoded[1], encoded[4], encoded[5]); | 411 y_out -= c->pic.linesize[0]; |
448 outptr[pixel_ptr++] = get_r(encoded[1], encoded[5]); | 412 u_out -= c->pic.linesize[1]; |
449 outptr[pixel_ptr++] = get_b(encoded[2], encoded[4]); | 413 v_out -= c->pic.linesize[2]; |
450 outptr[pixel_ptr++] = get_g(encoded[2], encoded[4], encoded[5]); | |
451 outptr[pixel_ptr++] = get_r(encoded[2], encoded[5]); | |
452 outptr[pixel_ptr++] = get_b(encoded[3], encoded[4]); | |
453 outptr[pixel_ptr++] = get_g(encoded[3], encoded[4], encoded[5]); | |
454 outptr[pixel_ptr++] = get_r(encoded[3], encoded[5]); | |
455 encoded += 6; | |
456 } | |
457 } | 414 } |
458 break; | 415 break; |
459 case IMGTYPE_YUV211: | 416 case IMGTYPE_YUV211: |
460 for (row = height - 1; row >= 0; row--) { | 417 for (row = 0; row < height; row++) { |
461 pixel_ptr = row * c->pic.linesize[0]; | 418 for (col = 0; col < width - 1; col += 2) { |
462 for (col = 0; col < width/2; col++) { | 419 memcpy(y_out + col, encoded, 2); |
463 outptr[pixel_ptr++] = get_b(encoded[0], encoded[2]); | 420 encoded += 2; |
464 outptr[pixel_ptr++] = get_g(encoded[0], encoded[2], encoded[3]); | 421 u_out[col >> 1] = *encoded++ + 128; |
465 outptr[pixel_ptr++] = get_r(encoded[0], encoded[3]); | 422 v_out[col >> 1] = *encoded++ + 128; |
466 outptr[pixel_ptr++] = get_b(encoded[1], encoded[2]); | 423 } |
467 outptr[pixel_ptr++] = get_g(encoded[1], encoded[2], encoded[3]); | 424 y_out -= c->pic.linesize[0]; |
468 outptr[pixel_ptr++] = get_r(encoded[1], encoded[3]); | 425 u_out -= c->pic.linesize[1]; |
469 encoded += 4; | 426 v_out -= c->pic.linesize[2]; |
470 } | |
471 } | 427 } |
472 break; | 428 break; |
473 case IMGTYPE_YUV420: | 429 case IMGTYPE_YUV420: |
474 for (row = height / 2 - 1; row >= 0; row--) { | 430 u_out = c->pic.data[1] + ((height >> 1) - 1) * c->pic.linesize[1]; |
475 pixel_ptr = 2 * row * c->pic.linesize[0]; | 431 v_out = c->pic.data[2] + ((height >> 1) - 1) * c->pic.linesize[2]; |
476 for (col = 0; col < width/2; col++) { | 432 for (row = 0; row < height - 1; row += 2) { |
477 outptr[pixel_ptr] = get_b(encoded[0], encoded[4]); | 433 for (col = 0; col < width - 1; col += 2) { |
478 outptr[pixel_ptr+1] = get_g(encoded[0], encoded[4], encoded[5]); | 434 memcpy(y_out + col, encoded, 2); |
479 outptr[pixel_ptr+2] = get_r(encoded[0], encoded[5]); | 435 encoded += 2; |
480 outptr[pixel_ptr+3] = get_b(encoded[1], encoded[4]); | 436 memcpy(y_out + col - c->pic.linesize[0], encoded, 2); |
481 outptr[pixel_ptr+4] = get_g(encoded[1], encoded[4], encoded[5]); | 437 encoded += 2; |
482 outptr[pixel_ptr+5] = get_r(encoded[1], encoded[5]); | 438 u_out[col >> 1] = *encoded++ + 128; |
483 outptr[pixel_ptr-c->pic.linesize[0]] = get_b(encoded[2], encoded[4]); | 439 v_out[col >> 1] = *encoded++ + 128; |
484 outptr[pixel_ptr-c->pic.linesize[0]+1] = get_g(encoded[2], encoded[4], encoded[5]); | 440 } |
485 outptr[pixel_ptr-c->pic.linesize[0]+2] = get_r(encoded[2], encoded[5]); | 441 y_out -= c->pic.linesize[0] << 1; |
486 outptr[pixel_ptr-c->pic.linesize[0]+3] = get_b(encoded[3], encoded[4]); | 442 u_out -= c->pic.linesize[1]; |
487 outptr[pixel_ptr-c->pic.linesize[0]+4] = get_g(encoded[3], encoded[4], encoded[5]); | 443 v_out -= c->pic.linesize[2]; |
488 outptr[pixel_ptr-c->pic.linesize[0]+5] = get_r(encoded[3], encoded[5]); | |
489 pixel_ptr += 6; | |
490 encoded += 6; | |
491 } | |
492 } | 444 } |
493 break; | 445 break; |
494 default: | 446 default: |
495 av_log(avctx, AV_LOG_ERROR, "BUG! Unknown imagetype in image decoder.\n"); | 447 av_log(avctx, AV_LOG_ERROR, "BUG! Unknown imagetype in image decoder.\n"); |
496 return -1; | 448 return -1; |
541 /* Detect image type */ | 493 /* Detect image type */ |
542 switch (c->imgtype = *((char *)avctx->extradata + 4)) { | 494 switch (c->imgtype = *((char *)avctx->extradata + 4)) { |
543 case IMGTYPE_YUV111: | 495 case IMGTYPE_YUV111: |
544 c->decomp_size = basesize * 3; | 496 c->decomp_size = basesize * 3; |
545 max_decomp_size = max_basesize * 3; | 497 max_decomp_size = max_basesize * 3; |
498 avctx->pix_fmt = PIX_FMT_YUV444P; | |
546 av_log(avctx, AV_LOG_INFO, "Image type is YUV 1:1:1.\n"); | 499 av_log(avctx, AV_LOG_INFO, "Image type is YUV 1:1:1.\n"); |
547 break; | 500 break; |
548 case IMGTYPE_YUV422: | 501 case IMGTYPE_YUV422: |
549 c->decomp_size = basesize * 2; | 502 c->decomp_size = basesize * 2; |
550 max_decomp_size = max_basesize * 2; | 503 max_decomp_size = max_basesize * 2; |
504 avctx->pix_fmt = PIX_FMT_YUV422P; | |
551 av_log(avctx, AV_LOG_INFO, "Image type is YUV 4:2:2.\n"); | 505 av_log(avctx, AV_LOG_INFO, "Image type is YUV 4:2:2.\n"); |
552 break; | 506 break; |
553 case IMGTYPE_RGB24: | 507 case IMGTYPE_RGB24: |
554 c->decomp_size = basesize * 3; | 508 c->decomp_size = basesize * 3; |
555 max_decomp_size = max_basesize * 3; | 509 max_decomp_size = max_basesize * 3; |
510 avctx->pix_fmt = PIX_FMT_BGR24; | |
556 av_log(avctx, AV_LOG_INFO, "Image type is RGB 24.\n"); | 511 av_log(avctx, AV_LOG_INFO, "Image type is RGB 24.\n"); |
557 break; | 512 break; |
558 case IMGTYPE_YUV411: | 513 case IMGTYPE_YUV411: |
559 c->decomp_size = basesize / 2 * 3; | 514 c->decomp_size = basesize / 2 * 3; |
560 max_decomp_size = max_basesize / 2 * 3; | 515 max_decomp_size = max_basesize / 2 * 3; |
516 avctx->pix_fmt = PIX_FMT_YUV411P; | |
561 av_log(avctx, AV_LOG_INFO, "Image type is YUV 4:1:1.\n"); | 517 av_log(avctx, AV_LOG_INFO, "Image type is YUV 4:1:1.\n"); |
562 break; | 518 break; |
563 case IMGTYPE_YUV211: | 519 case IMGTYPE_YUV211: |
564 c->decomp_size = basesize * 2; | 520 c->decomp_size = basesize * 2; |
565 max_decomp_size = max_basesize * 2; | 521 max_decomp_size = max_basesize * 2; |
522 avctx->pix_fmt = PIX_FMT_YUV422P; | |
566 av_log(avctx, AV_LOG_INFO, "Image type is YUV 2:1:1.\n"); | 523 av_log(avctx, AV_LOG_INFO, "Image type is YUV 2:1:1.\n"); |
567 break; | 524 break; |
568 case IMGTYPE_YUV420: | 525 case IMGTYPE_YUV420: |
569 c->decomp_size = basesize / 2 * 3; | 526 c->decomp_size = basesize / 2 * 3; |
570 max_decomp_size = max_basesize / 2 * 3; | 527 max_decomp_size = max_basesize / 2 * 3; |
528 avctx->pix_fmt = PIX_FMT_YUV420P; | |
571 av_log(avctx, AV_LOG_INFO, "Image type is YUV 4:2:0.\n"); | 529 av_log(avctx, AV_LOG_INFO, "Image type is YUV 4:2:0.\n"); |
572 break; | 530 break; |
573 default: | 531 default: |
574 av_log(avctx, AV_LOG_ERROR, "Unsupported image format %d.\n", c->imgtype); | 532 av_log(avctx, AV_LOG_ERROR, "Unsupported image format %d.\n", c->imgtype); |
575 return 1; | 533 return 1; |
654 #else | 612 #else |
655 av_log(avctx, AV_LOG_ERROR, "Zlib support not compiled.\n"); | 613 av_log(avctx, AV_LOG_ERROR, "Zlib support not compiled.\n"); |
656 return 1; | 614 return 1; |
657 #endif | 615 #endif |
658 } | 616 } |
659 | |
660 avctx->pix_fmt = PIX_FMT_BGR24; | |
661 | 617 |
662 return 0; | 618 return 0; |
663 } | 619 } |
664 | 620 |
665 /* | 621 /* |