[gimp-dds] / tags / release-2.0.6 / mipmap.c Repository:
ViewVC logotype

View of /tags/release-2.0.6/mipmap.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 118 - (download) (as text) (annotate)
Tue Jun 3 23:39:13 2008 UTC (17 months, 2 weeks ago) by cocidius
File size: 23606 byte(s)
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