Good references: squish library, stb_dxt.
| 14902 | |
| 14903 | // Good references: squish library, stb_dxt. |
| 14904 | void encode_bc1(void* pDst, const uint8_t* pPixels, uint32_t flags) |
| 14905 | { |
| 14906 | const color32* pSrc_pixels = (const color32*)pPixels; |
| 14907 | dxt1_block* pDst_block = static_cast<dxt1_block*>(pDst); |
| 14908 | |
| 14909 | int avg_r = -1, avg_g = 0, avg_b = 0; |
| 14910 | int lr = 0, lg = 0, lb = 0, hr = 0, hg = 0, hb = 0; |
| 14911 | uint8_t sels[16]; |
| 14912 | |
| 14913 | const bool use_sels = (flags & cEncodeBC1UseSelectors) != 0; |
| 14914 | if (use_sels) |
| 14915 | { |
| 14916 | // Caller is jamming in their own selectors for us to try. |
| 14917 | const uint32_t s = pDst_block->m_selectors[0] | (pDst_block->m_selectors[1] << 8) | (pDst_block->m_selectors[2] << 16) | (pDst_block->m_selectors[3] << 24); |
| 14918 | |
| 14919 | static const uint8_t s_sel_tran[4] = { 0, 3, 1, 2 }; |
| 14920 | |
| 14921 | for (uint32_t i = 0; i < 16; i++) |
| 14922 | sels[i] = s_sel_tran[(s >> (i * 2)) & 3]; |
| 14923 | } |
| 14924 | else |
| 14925 | { |
| 14926 | const uint32_t fr = pSrc_pixels[0].r, fg = pSrc_pixels[0].g, fb = pSrc_pixels[0].b; |
| 14927 | |
| 14928 | uint32_t j; |
| 14929 | for (j = 1; j < 16; j++) |
| 14930 | if ((pSrc_pixels[j].r != fr) || (pSrc_pixels[j].g != fg) || (pSrc_pixels[j].b != fb)) |
| 14931 | break; |
| 14932 | |
| 14933 | if (j == 16) |
| 14934 | { |
| 14935 | encode_bc1_solid_block(pDst, fr, fg, fb); |
| 14936 | return; |
| 14937 | } |
| 14938 | |
| 14939 | // Select 2 colors along the principle axis. (There must be a faster/simpler way.) |
| 14940 | int total_r = fr, total_g = fg, total_b = fb; |
| 14941 | int max_r = fr, max_g = fg, max_b = fb; |
| 14942 | int min_r = fr, min_g = fg, min_b = fb; |
| 14943 | for (uint32_t i = 1; i < 16; i++) |
| 14944 | { |
| 14945 | const int r = pSrc_pixels[i].r, g = pSrc_pixels[i].g, b = pSrc_pixels[i].b; |
| 14946 | max_r = basisu::maximum(max_r, r); max_g = basisu::maximum(max_g, g); max_b = basisu::maximum(max_b, b); |
| 14947 | min_r = basisu::minimum(min_r, r); min_g = basisu::minimum(min_g, g); min_b = basisu::minimum(min_b, b); |
| 14948 | total_r += r; total_g += g; total_b += b; |
| 14949 | } |
| 14950 | |
| 14951 | avg_r = (total_r + 8) >> 4; |
| 14952 | avg_g = (total_g + 8) >> 4; |
| 14953 | avg_b = (total_b + 8) >> 4; |
| 14954 | |
| 14955 | int icov[6] = { 0, 0, 0, 0, 0, 0 }; |
| 14956 | for (uint32_t i = 0; i < 16; i++) |
| 14957 | { |
| 14958 | int r = (int)pSrc_pixels[i].r - avg_r; |
| 14959 | int g = (int)pSrc_pixels[i].g - avg_g; |
| 14960 | int b = (int)pSrc_pixels[i].b - avg_b; |
| 14961 | icov[0] += r * r; |
no test coverage detected