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