MCPcopy Create free account
hub / github.com/citron-neo/emulator / interpolate

Function interpolate

externals/bc_decoder/bc_decoder.cpp:481–524  ·  view source on GitHub ↗

Interpolates between two endpoints, then does a final unquantization step

Source from the content-addressed store, hash-verified

479
480// Interpolates between two endpoints, then does a final unquantization step
481 Color interpolate(RGBf e0, RGBf e1, const IndexInfo &index, bool isSigned) {
482 static constexpr uint32_t weights3[] = {0, 9, 18, 27, 37, 46, 55, 64};
483 static constexpr uint32_t weights4[] = {0, 4, 9, 13, 17, 21, 26, 30,
484 34, 38, 43, 47, 51, 55, 60, 64};
485 static constexpr uint32_t const *weightsN[] = {
486 nullptr, nullptr, nullptr, weights3, weights4
487 };
488 auto weights = weightsN[index.numBits];
489 assert(weights != nullptr);
490 Color color;
491 uint32_t e0Weight = 64 - weights[index.value];
492 uint32_t e1Weight = weights[index.value];
493
494 for (int i = 0; i < RGBfChannels; i++) {
495 int32_t e0Channel = e0.channel[i];
496 int32_t e1Channel = e1.channel[i];
497
498 if (isSigned) {
499 e0Channel = extendSign(e0Channel, 16);
500 e1Channel = extendSign(e1Channel, 16);
501 }
502
503 int32_t e0Value = e0Channel * e0Weight;
504 int32_t e1Value = e1Channel * e1Weight;
505
506 uint32_t tmp = ((e0Value + e1Value + 32) >> 6);
507
508 // Need to unquantize value to limit it to the legal range of half-precision
509 // floats. We do this by scaling by 31/32 or 31/64 depending on if the value
510 // is signed or unsigned.
511 if (isSigned) {
512 tmp = ((tmp & 0x80000000) != 0) ? (((~tmp + 1) * 31) >> 5) | 0x8000 : (tmp * 31) >> 5;
513 // Don't return -0.0f, just normalize it to 0.0f.
514 if (tmp == 0x8000)
515 tmp = 0;
516 } else {
517 tmp = (tmp * 31) >> 6;
518 }
519
520 color.channel[i] = (uint16_t) tmp;
521 }
522
523 return color;
524 }
525
526 enum DataType {
527 // Endpoints

Callers 1

decodeMethod · 0.85

Calls 1

extendSignFunction · 0.85

Tested by

no test coverage detected