Parent Directory
|
Revision Log
Release 2.0.6 tag
1 /* 2 DDS GIMP plugin 3 4 Copyright (C) 2004-2008 Shawn Kirst <skirst@insightbb.com>, 5 with parts (C) 2003 Arne Reuter <homepage@arnereuter.de> where specified. 6 7 This program is free software; you can redistribute it and/or 8 modify it under the terms of the GNU General Public 9 License as published by the Free Software Foundation; either 10 version 2 of the License, or (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program; see the file COPYING. If not, write to 19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 20 Boston, MA 02111-1307, USA. 21 */ 22 23 #include <string.h> 24 #include <math.h> 25 26 #include <gtk/gtk.h> 27 28 #include "dds.h" 29 #include "mipmap.h" 30 #include "imath.h" 31 32 typedef void (*mipmapfunc_t)(unsigned char *, int, int, unsigned char *, int, int, int); 33 typedef void (*volmipmapfunc_t)(unsigned char *, int, int, int, unsigned char *, int, int, int, int); 34 35 int get_num_mipmaps(int width, int height, int format) 36 { 37 int w = width << 1; 38 int h = height << 1; 39 int n = 0; 40 41 if(format == DDS_COMPRESS_NONE) 42 { 43 while(w != 1 || h != 1) 44 { 45 if(w > 1) w >>= 1; 46 if(h > 1) h >>= 1; 47 ++n; 48 } 49 } 50 else 51 { 52 while(w > 4 && h > 4) 53 { 54 if(w > 4) w >>= 1; 55 if(h > 4) h >>= 1; 56 ++n; 57 } 58 } 59 60 return(n); 61 } 62 63 unsigned int get_mipmapped_size(int width, int height, int bpp, 64 int level, int num, int format) 65 { 66 int w, h, n = 0; 67 unsigned int size = 0; 68 69 w = width >> level; 70 h = height >> level; 71 if(w == 0) w = 1; 72 if(h == 0) h = 1; 73 w <<= 1; 74 h <<= 1; 75 76 while(n < num && (w != 1 || h != 1)) 77 { 78 if(w > 1) w >>= 1; 79 if(h > 1) h >>= 1; 80 if(format == DDS_COMPRESS_NONE) 81 size += (w * h); 82 else 83 size += ((w + 3) >> 2) * ((h + 3) >> 2); 84 ++n; 85 } 86 87 if(format == DDS_COMPRESS_NONE) 88 size *= bpp; 89 else 90 { 91 if(format == DDS_COMPRESS_BC1 || format == DDS_COMPRESS_BC4) 92 size *= 8; 93 else 94 size *= 16; 95 } 96 97 return(size); 98 } 99 100 unsigned int get_volume_mipmapped_size(int width, int height, 101 int depth, int bpp, int level, 102 int num, int format) 103 { 104 int w, h, d, n = 0; 105 unsigned int size = 0; 106 107 w = width >> level; 108 h = height >> level; 109 d = depth >> level; 110 if(w == 0) w = 1; 111 if(h == 0) h = 1; 112 if(d == 0) d = 1; 113 w <<= 1; 114 h <<= 1; 115 d <<= 1; 116 117 while(n < num && (w != 1 || h != 1)) 118 { 119 if(w > 1) w >>= 1; 120 if(h > 1) h >>= 1; 121 if(d > 1) d >>= 1; 122 if(format == DDS_COMPRESS_NONE) 123 size += (w * h * d); 124 else 125 size += (((w + 3) >> 2) * ((h + 3) >> 2) * d); 126 ++n; 127 } 128 129 if(format == DDS_COMPRESS_NONE) 130 size *= bpp; 131 else 132 { 133 if(format == DDS_COMPRESS_BC1 || format == DDS_COMPRESS_BC4) 134 size *= 8; 135 else 136 size *= 16; 137 } 138 139 return(size); 140 } 141 142 static void scale_image_nearest(unsigned char *dst, int dw, int dh, 143 unsigned char *src, int sw, int sh, 144 int bpp) 145 { 146 int n, x, y; 147 int ix, iy; 148 int srowbytes = sw * bpp; 149 int drowbytes = dw * bpp; 150 151 for(y = 0; y < dh; ++y) 152 { 153 iy = (y * sh + sh / 2) / dh; 154 for(x = 0; x < dw; ++x) 155 { 156 ix = (x * sw + sw / 2) / dw; 157 for(n = 0; n < bpp; ++n) 158 { 159 dst[y * drowbytes + (x * bpp) + n] = 160 src[iy * srowbytes + (ix * bpp) + n]; 161 } 162 } 163 } 164 } 165 166 static void scale_image_box(unsigned char *dst, int dw, int dh, 167 unsigned char *src, int sw, int sh, 168 int bpp) 169 { 170 int x, y, n, ix, iy, v; 171 int dstride = dw * bpp; 172 unsigned char *s; 173 174 for(y = 0; y < dh; ++y) 175 { 176 iy = (y * sh + sh / 2) / dh; 177 178 for(x = 0; x < dw; ++x) 179 { 180 ix = (x * sw + sh / 2) / dw; 181 182 s = src + (iy * sw + ix) * bpp; 183 184 for(n = 0; n < bpp; ++n) 185 { 186 v = (s[0] + s[bpp] + s[sw * bpp] + s[(sw + 1) * bpp]) >> 2; 187 dst[(y * dstride) + (x * bpp) + n] = v; 188 ++s; 189 } 190 } 191 } 192 } 193 194 static void scale_image_bilinear(unsigned char *dst, int dw, int dh, 195 unsigned char *src, int sw, int sh, 196 int bpp) 197 { 198 int x, y, n, ix, iy, wx, wy, v, v0, v1; 199 int dstride = dw * bpp; 200 unsigned char *s; 201 202 for(y = 0; y < dh; ++y) 203 { 204 if(dh > 1) 205 { 206 iy = (((sh - 1) * y) << 8) / (dh - 1); 207 if(y == dh - 1) --iy; 208 wy = iy & 0xff; 209 iy >>= 8; 210 } 211 else 212 iy = wy = 0; 213 214 for(x = 0; x < dw; ++x) 215 { 216 if(dw > 1) 217 { 218 ix = (((sw - 1) * x) << 8) / (dw - 1); 219 if(x == dw - 1) --ix; 220 wx = ix & 0xff; 221 ix >>= 8; 222 } 223 else 224 ix = wx = 0; 225 226 s = src + (iy * sw + ix) * bpp; 227 228 for(n = 0; n < bpp; ++n) 229 { 230 v0 = blerp(s[0], s[bpp], wx); 231 v1 = blerp(s[sw * bpp], s[(sw + 1) * bpp], wx); 232 v = blerp(v0, v1, wy); 233 if(v < 0) v = 0; 234 if(v > 255) v = 255; 235 dst[(y * dstride) + (x * bpp) + n] = v; 236 ++s; 237 } 238 } 239 } 240 } 241 242 static void scale_image_bicubic(unsigned char *dst, int dw, int dh, 243 unsigned char *src, int sw, int sh, 244 int bpp) 245 { 246 int x, y, n, ix, iy, wx, wy, v; 247 int a, b, c, d; 248 int dstride = dw * bpp; 249 unsigned char *s; 250 251 for(y = 0; y < dh; ++y) 252 { 253 if(dh > 1) 254 { 255 iy = (((sh - 1) * y) << 7) / (dh - 1); 256 if(y == dh - 1) --iy; 257 wy = iy & 0x7f; 258 iy >>= 7; 259 } 260 else 261 iy = wy = 0; 262 263 for(x = 0; x < dw; ++x) 264 { 265 if(dw > 1) 266 { 267 ix = (((sw - 1) * x) << 7) / (dw - 1); 268 if(x == dw - 1) --ix; 269 wx = ix & 0x7f; 270 ix >>= 7; 271 } 272 else 273 ix = wx = 0; 274 275 s = src + ((iy - 1) * sw + (ix - 1)) * bpp; 276 277 for(n = 0; n < bpp; ++n) 278 { 279 b = icerp(s[(sw + 0) * bpp], 280 s[(sw + 1) * bpp], 281 s[(sw + 2) * bpp], 282 s[(sw + 3) * bpp], wx); 283 if(iy > 0) 284 { 285 a = icerp(s[ 0], 286 s[ bpp], 287 s[2 * bpp], 288 s[3 * bpp], wx); 289 } 290 else 291 a = b; 292 293 c = icerp(s[(2 * sw + 0) * bpp], 294 s[(2 * sw + 1) * bpp], 295 s[(2 * sw + 2) * bpp], 296 s[(2 * sw + 3) * bpp], wx); 297 if(iy < dh - 1) 298 { 299 d = icerp(s[(3 * sw + 0) * bpp], 300 s[(3 * sw + 1) * bpp], 301 s[(3 * sw + 2) * bpp], 302 s[(3 * sw + 3) * bpp], wx); 303 } 304 else 305 d = c; 306 307 v = icerp(a, b, c, d, wy); 308 if(v < 0) v = 0; 309 if(v > 255) v = 255; 310 dst[(y * dstride) + (x * bpp) + n] = v; 311 ++s; 312 } 313 } 314 } 315 } 316 317 static const float FILTER_RADIUS = 5.0f; 318 319 static float lanczos(float r, float x) 320 { 321 float t; 322 if(x == 0.0f) return(1.0f); 323 if(x <= -r || x >= r) return(0.0f); 324 t = x * M_PI; 325 return(r * sinf(t) * sinf(t / r) / (t * t)); 326 } 327 328 static void scale_image_lanczos(unsigned char *dst, int dw, int dh, 329 unsigned char *src, int sw, int sh, 330 int bpp) 331 { 332 const float blur = 1.0f; 333 const float xfactor = (float)dw / (float)sw; 334 const float yfactor = (float)dh / (float)sh; 335 336 int x, y, start, stop, nmax, n, i; 337 int sstride = sw * bpp; 338 float center, contrib, density, s, r; 339 340 unsigned char *d, *row, *col; 341 342 float xscale = MIN(xfactor, 1.0f) / blur; 343 float yscale = MIN(yfactor, 1.0f) / blur; 344 float xsupport = FILTER_RADIUS / xscale; 345 float ysupport = FILTER_RADIUS / yscale; 346 347 if(xsupport <= 0.5f) 348 { 349 xsupport = 0.5f + 1e-12f; 350 xscale = 1.0f; 351 } 352 if(ysupport <= 0.5f) 353 { 354 ysupport = 0.5f + 1e-12f; 355 yscale = 1.0f; 356 } 357 358 /* resample in Y direction first to temporary buffer */ 359 unsigned char *tmp; 360 361 tmp = g_malloc(sw * dh * bpp); 362 d = tmp; 363 364 for(y = 0; y < dh; ++y) 365 { 366 for(x = 0; x < sw; ++x) 367 { 368 col = src + (x * bpp); 369 370 center = ((float)y + 0.5f) / yfactor; 371 start = (int)MAX(center - ysupport + 0.5f, 0); 372 stop = (int)MIN(center + ysupport + 0.5f, sh); 373 nmax = stop - start; 374 s = (float)start - center + 0.5f; 375 376 for(i = 0; i < bpp; ++i) 377 { 378 density = 0.0f; 379 r = 0.0f; 380 381 for(n = 0; n < nmax; ++n) 382 { 383 contrib = lanczos(FILTER_RADIUS, (s + n) * yscale); 384 density += contrib; 385 r += (float)col[((start + n) * sstride) + i] * contrib; 386 } 387 388 if(density != 0.0f && density != 1.0f) 389 r /= density; 390 391 if(r < 0) r = 0; 392 if(r > 255) r = 255; 393 394 *d++ = (unsigned char)r; 395 } 396 } 397 } 398 399 /* resample temp buffer in X direction */ 400 401 d = dst; 402 403 for(y = 0; y < dh; ++y) 404 { 405 row = tmp + (y * sstride); 406 407 for(x = 0; x < dw; ++x) 408 { 409 center = ((float)x + 0.5f) / xfactor; 410 start = (int)MAX(center - xsupport + 0.5f, 0); 411 stop = (int)MIN(center + xsupport + 0.5f, sw); 412 nmax = stop - start; 413 s = (float)start - center + 0.5f; 414 415 for(i = 0; i < bpp; ++i) 416 { 417 density = 0.0f; 418 r = 0.0f; 419 420 for(n = 0; n < nmax; ++n) 421 { 422 contrib = lanczos(FILTER_RADIUS, (s + n) * xscale); 423 density += contrib; 424 r += (float)row[((start + n) * bpp) + i] * contrib; 425 } 426 427 if(density != 0.0f && density != 1.0f) 428 r /= density; 429 430 if(r < 0) r = 0; 431 if(r > 255) r = 255; 432 433 *d++ = (unsigned char)r; 434 } 435 } 436 } 437 438 g_free(tmp); 439 } 440 441 int generate_mipmaps(unsigned char *dst, unsigned char *src, 442 unsigned int width, unsigned int height, int bpp, 443 int indexed, int mipmaps, int filter) 444 { 445 int i; 446 unsigned int sw, sh, dw, dh; 447 unsigned char *s, *d; 448 mipmapfunc_t mipmap_func = NULL; 449 450 if(indexed) 451 mipmap_func = scale_image_nearest; 452 else 453 { 454 switch(filter) 455 { 456 case DDS_MIPMAP_NEAREST: mipmap_func = scale_image_nearest; break; 457 case DDS_MIPMAP_BILINEAR: mipmap_func = scale_image_bilinear; break; 458 case DDS_MIPMAP_BICUBIC: mipmap_func = scale_image_bicubic; break; 459 case DDS_MIPMAP_LANCZOS: mipmap_func = scale_image_lanczos; break; 460 case DDS_MIPMAP_BOX: 461 default: mipmap_func = scale_image_box; break; 462 } 463 } 464 465 memcpy(dst, src, width * height * bpp); 466 467 s = dst; 468 d = dst + (width * height * bpp); 469 470 sw = width; 471 sh = height; 472 473 for(i = 1; i < mipmaps; ++i) 474 { 475 dw = sw >> 1; 476 dh = sh >> 1; 477 if(dw < 1) dw = 1; 478 if(dh < 1) dh = 1; 479 480 mipmap_func(d, dw, dh, s, sw, sh, bpp); 481 482 s = d; 483 sw = dw; 484 sh = dh; 485 d += (dw * dh * bpp); 486 } 487 488 return(1); 489 } 490 491 static void scale_volume_image_nearest(unsigned char *dst, int dw, int dh, int dd, 492 unsigned char *src, int sw, int sh, int sd, 493 int bpp) 494 { 495 int n, x, y, z; 496 int ix, iy, iz; 497 498 for(z = 0; z < dd; ++z) 499 { 500 iz = (z * sd + sd / 2) / dd; 501 for(y = 0; y < dh; ++y) 502 { 503 iy = (y * sh + sh / 2) / dh; 504 for(x = 0; x < dw; ++x) 505 { 506 ix = (x * sw + sw / 2) / dw; 507 for(n = 0; n < bpp; ++n) 508 { 509 dst[(z * (dw * dh)) + (y * dw) + (x * bpp) + n] = 510 src[(iz * (sw * sh)) + (iy * sw) + (ix * bpp) + n]; 511 } 512 } 513 } 514 } 515 } 516 517 static void scale_volume_image_box(unsigned char *dst, int dw, int dh, int dd, 518 unsigned char *src, int sw, int sh, int sd, 519 int bpp) 520 { 521 int n, x, y, z, v; 522 int ix, iy, iz; 523 unsigned char *s1, *s2, *d = dst; 524 525 for(z = 0; z < dd; ++z) 526 { 527 iz = (z * sd + sd / 2) / dd; 528 for(y = 0; y < dh; ++y) 529 { 530 iy = (y * sh + sh / 2) / dh; 531 for(x = 0; x < dw; ++x) 532 { 533 ix = (x * sw + sw / 2) / dw; 534 535 s1 = src + ((iz * (sw * sh)) + (iy * sw) + ix) * bpp; 536 if(iz < dd - 1) 537 s2 = src + (((iz + 1) * (sw * sh)) + (iy * sw) + ix) * bpp; 538 else 539 s2 = src; 540 541 for(n = 0; n < bpp; ++n) 542 { 543 v = 544 ((s1[0] + s1[bpp] + s1[sw * bpp] + s1[(sw + 1) * bpp]) + 545 (s2[0] + s2[bpp] + s2[sw * bpp] + s2[(sw + 1) * bpp])) >> 3; 546 *d++ = v; 547 ++s1; 548 ++s2; 549 } 550 } 551 } 552 } 553 } 554 555 static void scale_volume_image_bilinear(unsigned char *dst, int dw, int dh, int dd, 556 unsigned char *src, int sw, int sh, int sd, 557 int bpp) 558 { 559 int x, y, z, n, ix, iy, iz, wx, wy, wz, v, v0, v1, r0, r1; 560 unsigned char *s1, *s2, *d = dst; 561 562 for(z = 0; z < dd; ++z) 563 { 564 if(dd > 1) 565 { 566 iz = (((sd - 1) * z) << 8) / (dd - 1); 567 if(z == dd - 1) --iz; 568 wz = iz & 0xff; 569 iz >>= 8; 570 } 571 else 572 iz = wz = 0; 573 574 for(y = 0; y < dh; ++y) 575 { 576 if(dh > 1) 577 { 578 iy = (((sh - 1) * y) << 8) / (dh - 1); 579 if(y == dh - 1) --iy; 580 wy = iy & 0xff; 581 iy >>= 8; 582 } 583 else 584 iy = wy = 0; 585 586 for(x = 0; x < dw; ++x) 587 { 588 if(dw > 1) 589 { 590 ix = (((sw - 1) * x) << 8) / (dw - 1); 591 if(x == dw - 1) --ix; 592 wx = ix & 0xff; 593 ix >>= 8; 594 } 595 else 596 ix = wx = 0; 597 598 s1 = src + ((iz * (sw * sh)) + (iy * sw) + ix) * bpp; 599 s2 = src + (((iz + 1) * (sw * sh)) + (iy * sw) + ix) * bpp; 600 601 for(n = 0; n < bpp; ++n) 602 { 603 r0 = blerp(s1[0], s1[bpp], wx); 604 r1 = blerp(s1[sw * bpp], s1[(sw + 1) * bpp], wx); 605 v0 = blerp(r0, r1, wy); 606 607 r0 = blerp(s2[0], s2[bpp], wx); 608 r1 = blerp(s2[sw * bpp], s2[(sw + 1) * bpp], wx); 609 v1 = blerp(r0, r1, wy); 610 611 v = blerp(v0, v1, wz); 612 if(v < 0) v = 0; 613 if(v > 255) v = 255; 614 *d++ = v; 615 ++s1; 616 ++s2; 617 } 618 } 619 } 620 } 621 } 622 623 static void scale_volume_image_cubic(unsigned char *dst, int dw, int dh, int dd, 624 unsigned char *src, int sw, int sh, int sd, 625 int bpp) 626 { 627 int n, x, y, z; 628 int ix, iy, iz; 629 int wx, wy, wz; 630 int a, b, c, d; 631 int val, v0, v1, v2, v3; 632 int dstride = dw * bpp; 633 int sslice = sw * sh * bpp; 634 int dslice = dw * dh * bpp; 635 unsigned char *s0, *s1, *s2, *s3; 636 637 for(z = 0; z < dd; ++z) 638 { 639 if(dd > 1) 640 { 641 iz = (((sd - 1) * z) << 7) / (dd - 1); 642 if(z == dd - 1) --iz; 643 wz = iz & 0x7f; 644 iz >>= 7; 645 } 646 else 647 iz = wz = 0; 648 649 for(y = 0; y < dh; ++y) 650 { 651 if(dh > 1) 652 { 653 iy = (((sh - 1) * y) << 7) / (dh - 1); 654 if(y == dh - 1) --iy; 655 wy = iy & 0x7f; 656 iy >>= 7; 657 } 658 else 659 iy = wy = 0; 660 661 for(x = 0; x < dw; ++x) 662 { 663 if(dw > 1) 664 { 665 ix = (((sw - 1) * x) << 7) / (dw - 1); 666 if(x == dw - 1) --ix; 667 wx = ix & 0x7f; 668 ix >>= 7; 669 } 670 else 671 ix = wx = 0; 672 673 s0 = src + (((iz - 1) * (sw * sh)) + ((iy - 1) * sw) + (ix - 1)) * bpp; 674 s1 = s0 + sslice; 675 s2 = s1 + sslice; 676 s3 = s2 + sslice; 677 678 for(n = 0; n < bpp; ++n) 679 { 680 b = icerp(s1[(sw + 0) * bpp], 681 s1[(sw + 1) * bpp], 682 s1[(sw + 2) * bpp], 683 s1[(sw + 3) * bpp], wx); 684 if(iy > 0) 685 { 686 a = icerp(s1[ 0], 687 s1[ bpp], 688 s1[2 * bpp], 689 s1[3 * bpp], wx); 690 } 691 else 692 a = b; 693 694 c = icerp(s1[(2 * sw + 0) * bpp], 695 s1[(2 * sw + 1) * bpp], 696 s1[(2 * sw + 2) * bpp], 697 s1[(2 * sw + 3) * bpp], wx); 698 if(iy < dh - 1) 699 { 700 d = icerp(s1[(3 * sw + 0) * bpp], 701 s1[(3 * sw + 1) * bpp], 702 s1[(3 * sw + 2) * bpp], 703 s1[(3 * sw + 3) * bpp], wx); 704 } 705 else 706 d = c; 707 708 v1 = icerp(a, b, c, d, wy); 709 710 if(iz > 0) 711 { 712 b = icerp(s0[(sw + 0) * bpp], 713 s0[(sw + 1) * bpp], 714 s0[(sw + 2) * bpp], 715 s0[(sw + 3) * bpp], wx); 716 if(iy > 0) 717 { 718 a = icerp(s0[ 0], 719 s0[ bpp], 720 s0[2 * bpp], 721 s0[3 * bpp], wx); 722 } 723 else 724 a = b; 725 726 c = icerp(s0[(2 * sw + 0) * bpp], 727 s0[(2 * sw + 1) * bpp], 728 s0[(2 * sw + 2) * bpp], 729 s0[(2 * sw + 3) * bpp], wx); 730 if(iy < dh - 1) 731 { 732 d = icerp(s0[(3 * sw + 0) * bpp], 733 s0[(3 * sw + 1) * bpp], 734 s0[(3 * sw + 2) * bpp], 735 s0[(3 * sw + 3) * bpp], wx); 736 } 737 else 738 d = c; 739 740 v0 = icerp(a, b, c, d, wy); 741 } 742 else 743 v0 = v1; 744 745 b = icerp(s2[(sw + 0) * bpp], 746 s2[(sw + 1) * bpp], 747 s2[(sw + 2) * bpp], 748 s2[(sw + 3) * bpp], wx); 749 if(iy > 0) 750 { 751 a = icerp(s2[ 0], 752 s2[ bpp], 753 s2[2 * bpp], 754 s2[3 * bpp], wx); 755 } 756 else 757 a = b; 758 759 c = icerp(s2[(2 * sw + 0) * bpp], 760 s2[(2 * sw + 1) * bpp], 761 s2[(2 * sw + 2) * bpp], 762 s2[(2 * sw + 3) * bpp], wx); 763 if(iy < dh - 1) 764 { 765 d = icerp(s2[(3 * sw + 0) * bpp], 766 s2[(3 * sw + 1) * bpp], 767 s2[(3 * sw + 2) * bpp], 768 s2[(3 * sw + 3) * bpp], wx); 769 } 770 else 771 d = c; 772 773 v2 = icerp(a, b, c, d, wy); 774 775 if(iz < dd - 1) 776 { 777 b = icerp(s3[(sw + 0) * bpp], 778 s3[(sw + 1) * bpp], 779 s3[(sw + 2) * bpp], 780 s3[(sw + 3) * bpp], wx); 781 if(iy > 0) 782 { 783 a = icerp(s3[ 0], 784 s3[ bpp], 785 s3[2 * bpp], 786 s3[3 * bpp], wx); 787 } 788 else 789 a = b; 790 791 c = icerp(s3[(2 * sw + 0) * bpp], 792 s3[(2 * sw + 1) * bpp], 793 s3[(2 * sw + 2) * bpp], 794 s3[(2 * sw + 3) * bpp], wx); 795 if(iy < dh - 1) 796 { 797 d = icerp(s3[(3 * sw + 0) * bpp], 798 s3[(3 * sw + 1) * bpp], 799 s3[(3 * sw + 2) * bpp], 800 s3[(3 * sw + 3) * bpp], wx); 801 } 802 else 803 d = c; 804 805 v3 = icerp(a, b, c, d, wy); 806 } 807 else 808 v3 = v2; 809 810 val = icerp(v0, v1, v2, v3, wz); 811 812 if(val < 0) val = 0; 813 if(val > 255) val = 255; 814 815 dst[(z * dslice) + (y * dstride) + (x * bpp) + n] = val; 816 817 ++s0; 818 ++s1; 819 ++s2; 820 ++s3; 821 } 822 } 823 } 824 } 825 } 826 827 int generate_volume_mipmaps(unsigned char *dst, unsigned char *src, 828 unsigned int width, unsigned int height, 829 unsigned int depth, int bpp, int indexed, 830 int mipmaps, int filter) 831 { 832 int i; 833 unsigned int sw, sh, sd; 834 unsigned int dw, dh, dd; 835 unsigned char *s, *d; 836 volmipmapfunc_t mipmap_func = NULL; 837 838 if(indexed) 839 mipmap_func = scale_volume_image_nearest; 840 else 841 { 842 switch(filter) 843 { 844 case DDS_MIPMAP_NEAREST: mipmap_func = scale_volume_image_nearest; break; 845 case DDS_MIPMAP_BILINEAR: mipmap_func = scale_volume_image_bilinear; break; 846 case DDS_MIPMAP_BICUBIC: mipmap_func = scale_volume_image_cubic; break; 847 case DDS_MIPMAP_BOX: 848 default: 849 mipmap_func = scale_volume_image_box; break; 850 } 851 } 852 853 memcpy(dst, src, width * height * depth * bpp); 854 855 s = dst; 856 d = dst + (width * height * depth * bpp); 857 858 sw = width; 859 sh = height; 860 sd = depth; 861 862 for(i = 1; i < mipmaps; ++i) 863 { 864 dw = sw >> 1; 865 dh = sh >> 1; 866 dd = sd >> 1; 867 if(dw < 1) dw = 1; 868 if(dh < 1) dh = 1; 869 if(dd < 1) dd = 1; 870 871 mipmap_func(d, dw, dh, dd, s, sw, sh, sd, bpp); 872 873 s = d; 874 sw = dw; 875 sh = dh; 876 sd = dd; 877 d += (dw * dh * dd * bpp); 878 } 879 880 return(1); 881 }
| ViewVC Help | |
| Powered by ViewVC 1.0.4 |