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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 112 - (download) (as text) (annotate)
Sat May 10 00:44:43 2008 UTC (18 months, 1 week ago) by cocidius
File size: 23398 byte(s)
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