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