| 421 | /* pack a DXT 4x4 cell; px = 16 RGB colors; nstep = 2 or 3; dest = 8 bytes */ |
| 422 | |
| 423 | int score_dxt(unsigned long *px, int nstep, unsigned long col1, |
| 424 | unsigned long col2, unsigned long *pack) |
| 425 | { |
| 426 | unsigned char *p1,*p2,*p; |
| 427 | int vec[3],vdir[3],v2,xa2,xav; |
| 428 | int i,score,choice; |
| 429 | |
| 430 | p1 = (unsigned char *)&col1; |
| 431 | p2 = (unsigned char *)&col2; |
| 432 | vdir[0] = (int)p2[0] - (int)p1[0]; |
| 433 | vdir[1] = (int)p2[1] - (int)p1[1]; |
| 434 | vdir[2] = (int)p2[2] - (int)p1[2]; |
| 435 | v2 = vdir[0]*vdir[0] + vdir[1]*vdir[1] + vdir[2]*vdir[2]; |
| 436 | score=0; |
| 437 | *pack=0; |
| 438 | p=(unsigned char *)(px+15); |
| 439 | for (i=15;i>=0;i--,p-=4) { |
| 440 | vec[0] = (int)p[0] - (int)p1[0]; |
| 441 | vec[1] = (int)p[1] - (int)p1[1]; |
| 442 | vec[2] = (int)p[2] - (int)p1[2]; |
| 443 | xa2 = vec[0]*vec[0] + vec[1]*vec[1] + vec[2]*vec[2]; |
| 444 | xav = vec[0]*vdir[0] + vec[1]*vdir[1] + vec[2]*vdir[2]; |
| 445 | if (v2) choice = (nstep*xav+(v2>>1))/v2; else choice = 0; |
| 446 | if (choice<0) choice = 0; |
| 447 | if (choice>nstep) choice = nstep; |
| 448 | score += xa2 - (2*choice*xav)/nstep + (choice*choice*v2)/(nstep*nstep); |
| 449 | *pack=(*pack)<<2; |
| 450 | if (choice == nstep) (*pack)++; /* encode: 1 */ |
| 451 | else if (choice) *pack += (choice+1); /* encode: 2 or 3 */ |
| 452 | } |
| 453 | return score; |
| 454 | } |
| 455 | |
| 456 | void pack_dxt(unsigned long *px, unsigned char *dest) |
| 457 | { |