| 439 | } |
| 440 | |
| 441 | static void run_postproc(AVCodecContext *avctx, AVFrame *frame) |
| 442 | { |
| 443 | DDSContext *ctx = avctx->priv_data; |
| 444 | int i, x_off; |
| 445 | |
| 446 | switch (ctx->postproc) { |
| 447 | case DDS_ALPHA_EXP: |
| 448 | /* Alpha-exponential mode divides each channel by the maximum |
| 449 | * R, G or B value, and stores the multiplying factor in the |
| 450 | * alpha channel. */ |
| 451 | av_log(avctx, AV_LOG_DEBUG, "Post-processing alpha exponent.\n"); |
| 452 | |
| 453 | for (i = 0; i < frame->linesize[0] * frame->height; i += 4) { |
| 454 | uint8_t *src = frame->data[0] + i; |
| 455 | int r = src[0]; |
| 456 | int g = src[1]; |
| 457 | int b = src[2]; |
| 458 | int a = src[3]; |
| 459 | |
| 460 | src[0] = r * a / 255; |
| 461 | src[1] = g * a / 255; |
| 462 | src[2] = b * a / 255; |
| 463 | src[3] = 255; |
| 464 | } |
| 465 | break; |
| 466 | case DDS_NORMAL_MAP: |
| 467 | /* Normal maps work in the XYZ color space and they encode |
| 468 | * X in R or in A, depending on the texture type, Y in G and |
| 469 | * derive Z with a square root of the distance. |
| 470 | * |
| 471 | * http://www.realtimecollisiondetection.net/blog/?p=28 */ |
| 472 | av_log(avctx, AV_LOG_DEBUG, "Post-processing normal map.\n"); |
| 473 | |
| 474 | x_off = ctx->dec.tex_ratio == 8 ? 0 : 3; |
| 475 | for (i = 0; i < frame->linesize[0] * frame->height; i += 4) { |
| 476 | uint8_t *src = frame->data[0] + i; |
| 477 | int x = src[x_off]; |
| 478 | int y = src[1]; |
| 479 | int z = 127; |
| 480 | |
| 481 | int d = (255 * 255 - x * x - y * y) / 2; |
| 482 | if (d > 0) |
| 483 | z = lrint(sqrtf(d)); |
| 484 | |
| 485 | src[0] = x; |
| 486 | src[1] = y; |
| 487 | src[2] = z; |
| 488 | src[3] = 255; |
| 489 | } |
| 490 | break; |
| 491 | case DDS_RAW_YCOCG: |
| 492 | /* Data is Y-Co-Cg-A and not RGBA, but they are represented |
| 493 | * with the same masks in the DDPF header. */ |
| 494 | av_log(avctx, AV_LOG_DEBUG, "Post-processing raw YCoCg.\n"); |
| 495 | |
| 496 | for (i = 0; i < frame->linesize[0] * frame->height; i += 4) { |
| 497 | uint8_t *src = frame->data[0] + i; |
| 498 | int a = src[0]; |
no test coverage detected