[gimp-dds] / tags / release-2.0.1 / ddsread.c Repository:
ViewVC logotype

View of /tags/release-2.0.1/ddsread.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 88 - (download) (as text) (annotate)
Wed Nov 7 23:49:28 2007 UTC (2 years ago) by cocidius
File size: 24733 byte(s)
Replacing 2.0.1 release tag, phase 2 of 2
    1 /*
    2    DDS GIMP plugin
    3 
    4    Copyright (C) 2004 Shawn Kirst <skirst@fuse.net>,
    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 /*
   24 ** !!! COPYRIGHT NOTICE !!!
   25 **
   26 ** The following is based on code (C) 2003 Arne Reuter <homepage@arnereuter.de>
   27 ** URL: http://www.dr-reuter.de/arne/dds.html
   28 **
   29 */
   30 
   31 #include <stdio.h>
   32 #include <stdlib.h>
   33 #include <string.h>
   34 
   35 #include <gtk/gtk.h>
   36 
   37 #include <libgimp/gimp.h>
   38 #include <libgimp/gimpui.h>
   39 
   40 #include "ddsplugin.h"
   41 #include "dds.h"
   42 #include "dxt.h"
   43 #include "endian.h"
   44 
   45 typedef struct
   46 {
   47    unsigned char rshift, gshift, bshift, ashift;
   48    unsigned char rbits, gbits, bbits, abits;
   49    unsigned int rmask, gmask, bmask, amask;
   50    unsigned int bpp, gimp_bpp;
   51    int tile_height;
   52    unsigned char *palette;
   53 } dds_load_info_t;
   54 
   55 static int read_header(dds_header_t *hdr, FILE *fp);
   56 static int validate_header(dds_header_t *hdr);
   57 static int load_layer(FILE *fp, dds_header_t *hdr, dds_load_info_t *d,
   58                       gint32 image, unsigned int level, char *prefix,
   59                       unsigned int *l, guchar *pixels, unsigned char *buf);
   60 static int load_mipmaps(FILE *fp, dds_header_t *hdr, dds_load_info_t *d,
   61                         gint32 image, char *prefix, unsigned int *l,
   62                         guchar *pixels, unsigned char *buf);
   63 static int load_face(FILE *fp, dds_header_t *hdr, dds_load_info_t *d,
   64                      gint32 image, char *prefix, unsigned int *l,
   65                      guchar *pixels, unsigned char *buf);
   66 static unsigned char color_bits(unsigned int mask);
   67 static unsigned char color_shift(unsigned int mask);
   68 
   69 gint32 read_dds(gchar *filename)
   70 {
   71    gint32 image = 0;
   72    unsigned char *buf;
   73    unsigned int l = 0;
   74    guchar *pixels;
   75    gchar *tmp;
   76    FILE *fp;
   77    dds_header_t hdr;
   78    dds_load_info_t d;
   79    gint *layers, layer_count;
   80    GimpImageBaseType type;
   81    int i, j;
   82 
   83    fp = fopen(filename, "rb");
   84    if(fp == 0)
   85    {
   86       g_message("Error opening file.\n");
   87       return(-1);
   88    }
   89 
   90    if(interactive_dds)
   91    {
   92       if(strrchr(filename, '/'))
   93          tmp = g_strdup_printf("Loading %s:", strrchr(filename, '/') + 1);
   94       else
   95          tmp = g_strdup_printf("Loading %s:", filename);
   96       gimp_progress_init(tmp);
   97       g_free(tmp);
   98    }
   99 
  100    read_header(&hdr, fp);
  101    if(!validate_header(&hdr))
  102    {
  103       fclose(fp);
  104       return(-1);
  105    }
  106 
  107    /* a lot of DDS images out there don't have this for some reason -_- */
  108    if(hdr.pitch_or_linsize == 0)
  109    {
  110       if(hdr.pixelfmt.flags & DDPF_FOURCC) /* assume linear size */
  111       {
  112          hdr.pitch_or_linsize = ((hdr.width + 3) >> 2) * ((hdr.height + 3) >> 2);
  113          if(hdr.pixelfmt.fourcc[3] == '1')
  114             hdr.pitch_or_linsize *= 8;
  115          else
  116             hdr.pitch_or_linsize *= 16;
  117       }
  118       else /* assume pitch */
  119       {
  120          hdr.pitch_or_linsize = hdr.height * hdr.width *
  121             (hdr.pixelfmt.bpp >> 3);
  122       }
  123    }
  124 
  125    if(hdr.pixelfmt.flags & DDPF_FOURCC)
  126    {
  127       if(hdr.pixelfmt.fourcc[0] == 'D')
  128          hdr.pixelfmt.flags |= DDPF_ALPHAPIXELS;
  129    }
  130 
  131    if(hdr.pixelfmt.flags & DDPF_FOURCC)
  132    {
  133       switch(GETL32(hdr.pixelfmt.fourcc))
  134       {
  135          case CHAR32('A', 'T', 'I', '1'):
  136             d.bpp = d.gimp_bpp = 1;
  137             type = GIMP_GRAY;
  138             break;
  139          case CHAR32('A', 'T', 'I', '2'):
  140             d.bpp = d.gimp_bpp = 3;
  141             type = GIMP_RGB;
  142             break;
  143          default:
  144             d.bpp = d.gimp_bpp = 4;
  145             type = GIMP_RGB;
  146             break;
  147       }
  148    }
  149    else
  150    {
  151       d.bpp = hdr.pixelfmt.bpp >> 3;
  152 
  153       if(d.bpp == 2)
  154       {
  155          if(hdr.pixelfmt.amask == 0xf000) // RGBA4
  156          {
  157             d.gimp_bpp = 4;
  158             type = GIMP_RGB;
  159          }
  160          else if(hdr.pixelfmt.amask == 0xff00) //L8A8
  161          {
  162             d.gimp_bpp = 2;
  163             type = GIMP_GRAY;
  164          }
  165          else if(hdr.pixelfmt.bmask == 0x1f) //R5G6B5 or RGB5A1
  166          {
  167             if(hdr.pixelfmt.amask == 0x8000) // RGB5A1
  168                d.gimp_bpp = 4;
  169             else
  170                d.gimp_bpp = 3;
  171 
  172             type = GIMP_RGB;
  173          }
  174          else //L16
  175          {
  176             d.gimp_bpp = 1;
  177             type = GIMP_GRAY;
  178          }
  179       }
  180       else
  181       {
  182          if(hdr.pixelfmt.flags & DDPF_PALETTEINDEXED8)
  183          {
  184             type = GIMP_INDEXED;
  185             d.gimp_bpp = 1;
  186          }
  187          else if(hdr.pixelfmt.rmask == 0xe0) // R3G3B2
  188          {
  189             type = GIMP_RGB;
  190             d.gimp_bpp = 3;
  191          }
  192          else
  193          {
  194             d.gimp_bpp = d.bpp;
  195             type = (d.bpp == 1) ? GIMP_GRAY : GIMP_RGB;
  196          }
  197       }
  198    }
  199 
  200    image = gimp_image_new(hdr.width, hdr.height, type);
  201 
  202    if(image == -1)
  203    {
  204       g_message("Can't allocate new image.\n");
  205       fclose(fp);
  206       return(-1);
  207    }
  208 
  209    gimp_image_set_filename(image, filename);
  210 
  211    if(hdr.pixelfmt.flags & DDPF_PALETTEINDEXED8)
  212    {
  213       d.palette = g_malloc(256 * 4);
  214       fread(d.palette, 1, 256 * 4, fp);
  215       for(i = j = 0; i < 768; i += 3, j += 4)
  216       {
  217          d.palette[i + 0] = d.palette[j + 0];
  218          d.palette[i + 1] = d.palette[j + 1];
  219          d.palette[i + 2] = d.palette[j + 2];
  220       }
  221       gimp_image_set_colormap(image, d.palette, 256);
  222    }
  223 
  224    d.tile_height = gimp_tile_height();
  225 
  226    pixels = g_new(guchar, d.tile_height * hdr.width * d.gimp_bpp);
  227    buf = g_malloc(hdr.pitch_or_linsize);
  228 
  229    d.rshift = color_shift(hdr.pixelfmt.rmask);
  230    d.gshift = color_shift(hdr.pixelfmt.gmask);
  231    d.bshift = color_shift(hdr.pixelfmt.bmask);
  232    d.ashift = color_shift(hdr.pixelfmt.amask);
  233    d.rbits = color_bits(hdr.pixelfmt.rmask);
  234    d.gbits = color_bits(hdr.pixelfmt.gmask);
  235    d.bbits = color_bits(hdr.pixelfmt.bmask);
  236    d.abits = color_bits(hdr.pixelfmt.amask);
  237    d.rmask = hdr.pixelfmt.rmask >> d.rshift << (8 - d.rbits);
  238    d.gmask = hdr.pixelfmt.gmask >> d.gshift << (8 - d.gbits);
  239    d.bmask = hdr.pixelfmt.bmask >> d.bshift << (8 - d.bbits);
  240    d.amask = hdr.pixelfmt.amask >> d.ashift << (8 - d.abits);
  241 
  242    if(!(hdr.caps.caps2 & DDSCAPS2_CUBEMAP) &&
  243       !(hdr.caps.caps2 & DDSCAPS2_VOLUME))
  244    {
  245       if(!load_layer(fp, &hdr, &d, image, 0, "", &l, pixels, buf))
  246       {
  247          fclose(fp);
  248          gimp_image_delete(image);
  249          return(-1);
  250       }
  251    }
  252 
  253    if(hdr.caps.caps1 & DDSCAPS_COMPLEX)
  254    {
  255       if(hdr.caps.caps2 & DDSCAPS2_CUBEMAP)
  256       {
  257          if((hdr.caps.caps2 & DDSCAPS2_CUBEMAP_POSITIVEX) &&
  258             !load_face(fp, &hdr, &d, image, "(positive x)", &l, pixels, buf))
  259          {
  260             fclose(fp);
  261             gimp_image_delete(image);
  262             return(-1);
  263          }
  264          if((hdr.caps.caps2 & DDSCAPS2_CUBEMAP_NEGATIVEX) &&
  265             !load_face(fp, &hdr, &d, image, "(negative x)", &l, pixels, buf))
  266          {
  267             fclose(fp);
  268             gimp_image_delete(image);
  269             return(-1);
  270          }
  271          if((hdr.caps.caps2 & DDSCAPS2_CUBEMAP_POSITIVEY) &&
  272             !load_face(fp, &hdr, &d, image, "(positive y)", &l, pixels, buf))
  273          {
  274             fclose(fp);
  275             gimp_image_delete(image);
  276             return(-1);
  277          }
  278          if((hdr.caps.caps2 & DDSCAPS2_CUBEMAP_NEGATIVEY) &&
  279             !load_face(fp, &hdr, &d, image, "(negative y)", &l, pixels, buf))
  280          {
  281             fclose(fp);
  282             gimp_image_delete(image);
  283             return(-1);
  284          }
  285          if((hdr.caps.caps2 & DDSCAPS2_CUBEMAP_POSITIVEZ) &&
  286             !load_face(fp, &hdr, &d, image, "(positive z)", &l, pixels, buf))
  287          {
  288             fclose(fp);
  289             gimp_image_delete(image);
  290             return(-1);
  291          }
  292          if((hdr.caps.caps2 & DDSCAPS2_CUBEMAP_NEGATIVEZ) &&
  293             !load_face(fp, &hdr, &d, image, "(negative z)", &l, pixels, buf))
  294          {
  295             fclose(fp);
  296             gimp_image_delete(image);
  297             return(-1);
  298          }
  299       }
  300       else if((hdr.caps.caps2 & DDSCAPS2_VOLUME) &&
  301               (hdr.flags & DDSD_DEPTH))
  302       {
  303          unsigned int i, level;
  304          char *plane;
  305          for(i = 0; i < hdr.depth; ++i)
  306          {
  307             plane = g_strdup_printf("(z = %d)", i);
  308             if(!load_layer(fp, &hdr, &d, image, 0, plane, &l, pixels, buf))
  309             {
  310                g_free(plane);
  311                fclose(fp);
  312                gimp_image_delete(image);
  313                return(-1);
  314             }
  315             g_free(plane);
  316          }
  317 
  318          if((hdr.flags & DDSD_MIPMAPCOUNT) &&
  319             (hdr.caps.caps1 & DDSCAPS_MIPMAP))
  320          {
  321             for(level = 1; level < hdr.num_mipmaps; ++level)
  322             {
  323                int n = hdr.depth >> level;
  324                if(n < 1) n = 1;
  325                for(i = 0; i < n; ++i)
  326                {
  327                   plane = g_strdup_printf("(z = %d)", i);
  328                   if(!load_layer(fp, &hdr, &d, image, level, plane, &l, pixels, buf))
  329                   {
  330                      g_free(plane);
  331                      fclose(fp);
  332                      gimp_image_delete(image);
  333                      return(-1);
  334                   }
  335                   g_free(plane);
  336                }
  337             }
  338          }
  339       }
  340       else if(!load_mipmaps(fp, &hdr, &d, image, "", &l, pixels, buf))
  341       {
  342          fclose(fp);
  343          gimp_image_delete(image);
  344          return(-1);
  345       }
  346    }
  347 
  348    if(hdr.pixelfmt.flags & DDPF_PALETTEINDEXED8)
  349       g_free(d.palette);
  350 
  351    g_free(buf);
  352    g_free(pixels);
  353    fclose(fp);
  354 
  355    layers = gimp_image_get_layers(image, &layer_count);
  356    gimp_image_set_active_layer(image, layers[0]);
  357 
  358    return(image);
  359 }
  360 
  361 static int read_header(dds_header_t *hdr, FILE *fp)
  362 {
  363    unsigned char buf[DDS_HEADERSIZE];
  364 
  365    memset(hdr, 0, sizeof(dds_header_t));
  366 
  367    if(fread(buf, 1, DDS_HEADERSIZE, fp) != DDS_HEADERSIZE)
  368       return(0);
  369 
  370    hdr->magic[0] = buf[0];
  371    hdr->magic[1] = buf[1];
  372    hdr->magic[2] = buf[2];
  373    hdr->magic[3] = buf[3];
  374 
  375    hdr->size = GETL32(buf + 4);
  376    hdr->flags = GETL32(buf + 8);
  377    hdr->height = GETL32(buf + 12);
  378    hdr->width = GETL32(buf + 16);
  379    hdr->pitch_or_linsize = GETL32(buf + 20);
  380    hdr->depth = GETL32(buf + 24);
  381    hdr->num_mipmaps = GETL32(buf + 28);
  382 
  383    hdr->pixelfmt.size = GETL32(buf + 76);
  384    hdr->pixelfmt.flags = GETL32(buf + 80);
  385    hdr->pixelfmt.fourcc[0] = buf[84];
  386    hdr->pixelfmt.fourcc[1] = buf[85];
  387    hdr->pixelfmt.fourcc[2] = buf[86];
  388    hdr->pixelfmt.fourcc[3] = buf[87];
  389    hdr->pixelfmt.bpp = GETL32(buf + 88);
  390    hdr->pixelfmt.rmask = GETL32(buf + 92);
  391    hdr->pixelfmt.gmask = GETL32(buf + 96);
  392    hdr->pixelfmt.bmask = GETL32(buf + 100);
  393    hdr->pixelfmt.amask = GETL32(buf + 104);
  394 
  395    hdr->caps.caps1 = GETL32(buf + 108);
  396    hdr->caps.caps2 = GETL32(buf + 112);
  397 
  398    return(1);
  399 }
  400 
  401 static int validate_header(dds_header_t *hdr)
  402 {
  403    if(memcmp(hdr->magic, "DDS ", 4))
  404    {
  405       g_message("Invalid DDS file.\n");
  406       return(0);
  407    }
  408 
  409    if((hdr->flags & DDSD_PITCH) == (hdr->flags & DDSD_LINEARSIZE))
  410    {
  411       //g_message("Warning: DDSD_PITCH or DDSD_LINEARSIZE is not set.\n");
  412       if(hdr->pixelfmt.flags & DDPF_FOURCC)
  413          hdr->flags |= DDSD_LINEARSIZE;
  414       else
  415          hdr->flags |= DDSD_PITCH;
  416    }
  417 /*
  418    if((hdr->pixelfmt.flags & DDPF_FOURCC) ==
  419       (hdr->pixelfmt.flags & DDPF_RGB))
  420    {
  421       g_message("Invalid pixel format.\n");
  422       return(0);
  423    }
  424 */
  425    if((hdr->pixelfmt.flags & DDPF_FOURCC) &&
  426       memcmp(hdr->pixelfmt.fourcc, "DXT1", 4) &&
  427       memcmp(hdr->pixelfmt.fourcc, "DXT3", 4) &&
  428       memcmp(hdr->pixelfmt.fourcc, "DXT5", 4) &&
  429       memcmp(hdr->pixelfmt.fourcc, "ATI1", 4) &&
  430       memcmp(hdr->pixelfmt.fourcc, "ATI2", 4))
  431    {
  432       g_message("Invalid compression format.\n"
  433                 "Only DXT1, DXT3, DXT5, ATI1N and ATI2N formats are supported.\n");
  434       return(0);
  435    }
  436 
  437    if(hdr->pixelfmt.flags & DDPF_RGB)
  438    {
  439       if((hdr->pixelfmt.bpp !=  8) &&
  440          (hdr->pixelfmt.bpp != 16) &&
  441          (hdr->pixelfmt.bpp != 24) &&
  442          (hdr->pixelfmt.bpp != 32))
  443       {
  444          g_message("Invalid BPP.\n");
  445          return(0);
  446       }
  447    }
  448    else if(hdr->pixelfmt.flags & DDPF_LUMINANCE)
  449    {
  450       if((hdr->pixelfmt.bpp !=  8) &&
  451          (hdr->pixelfmt.bpp != 16))
  452       {
  453          g_message("Invalid BPP.\n");
  454          return(0);
  455       }
  456 
  457       hdr->pixelfmt.flags |= DDPF_RGB;
  458    }
  459    else if(hdr->pixelfmt.flags & DDPF_PALETTEINDEXED8)
  460    {
  461       hdr->pixelfmt.flags |= DDPF_RGB;
  462    }
  463 
  464    if(!(hdr->pixelfmt.flags & DDPF_RGB) &&
  465       !(hdr->pixelfmt.flags & DDPF_FOURCC) &&
  466       !(hdr->pixelfmt.flags & DDPF_LUMINANCE))
  467    {
  468       g_message("Unknown pixel format!  Taking a guess, expect trouble!");
  469       switch(GETL32(hdr->pixelfmt.fourcc))
  470       {
  471          case CHAR32('D', 'X', 'T', '1'):
  472          case CHAR32('D', 'X', 'T', '3'):
  473          case CHAR32('D', 'X', 'T', '5'):
  474          case CHAR32('A', 'T', 'I', '1'):
  475          case CHAR32('A', 'T', 'I', '2'):
  476             hdr->pixelfmt.flags |= DDPF_FOURCC;
  477             break;
  478          default:
  479             switch(hdr->pixelfmt.bpp)
  480             {
  481                case 8:
  482                   hdr->pixelfmt.flags |= DDPF_LUMINANCE;
  483                   break;
  484                case 16:
  485                case 24:
  486                case 32:
  487                   hdr->pixelfmt.flags |= DDPF_RGB;
  488                   break;
  489                default:
  490                   g_message("Invalid pixel format.");
  491                   return(0);
  492             }
  493             break;
  494       }
  495    }
  496 
  497    return(1);
  498 }
  499 
  500 static int load_layer(FILE *fp, dds_header_t *hdr, dds_load_info_t *d,
  501                       gint32 image, unsigned int level, char *prefix,
  502                       unsigned int *l, guchar *pixels, unsigned char *buf)
  503 {
  504    GimpDrawable *drawable;
  505    GimpPixelRgn pixel_region;
  506    GimpImageType type = GIMP_RGBA_IMAGE;
  507    gchar *layer_name;
  508    gint x, y, z, n;
  509    gint32 layer;
  510    unsigned int width = hdr->width >> level;
  511    unsigned int height = hdr->height >> level;
  512    unsigned int size = hdr->pitch_or_linsize >> (2 * level);
  513    int format = DDS_COMPRESS_NONE;
  514 
  515    if(width < 1) width = 1;
  516    if(height < 1) height = 1;
  517 
  518    switch(d->bpp)
  519    {
  520       case 1:
  521          if(hdr->pixelfmt.flags & DDPF_PALETTEINDEXED8)
  522             type = GIMP_INDEXED_IMAGE;
  523          else if(hdr->pixelfmt.rmask == 0xe0)
  524             type = GIMP_RGB_IMAGE;
  525          else
  526             type = GIMP_GRAY_IMAGE;
  527          break;
  528       case 2:
  529          if(hdr->pixelfmt.amask == 0xf000) //RGBA4
  530             type = GIMP_RGBA_IMAGE;
  531          else if(hdr->pixelfmt.amask == 0xff00) //L8A8
  532             type = GIMP_GRAYA_IMAGE;
  533          else if(hdr->pixelfmt.bmask == 0x1f) //R5G6B5 or RGB5A1
  534             type = (hdr->pixelfmt.amask == 0x8000) ? GIMP_RGBA_IMAGE : GIMP_RGB_IMAGE;
  535          else //L16
  536             type = GIMP_GRAY_IMAGE;
  537          break;
  538       case 3: type = GIMP_RGB_IMAGE;   break;
  539       case 4: type = GIMP_RGBA_IMAGE;  break;
  540    }
  541 
  542    layer_name = (level) ? g_strdup_printf("mipmap %d %s", level, prefix) :
  543                           g_strdup_printf("main surface %s", prefix);
  544 
  545    layer = gimp_layer_new(image, layer_name, width, height, type, 100,
  546                           GIMP_NORMAL_MODE);
  547    g_free(layer_name);
  548 
  549    gimp_image_add_layer(image, layer, *l);
  550    if((*l)++) gimp_drawable_set_visible(layer, FALSE);
  551 
  552    drawable = gimp_drawable_get(layer);
  553 
  554    gimp_pixel_rgn_init(&pixel_region, drawable, 0, 0, drawable->width,
  555                        drawable->height, TRUE, FALSE);
  556 
  557    if(hdr->pixelfmt.flags & DDPF_FOURCC)
  558    {
  559       unsigned int w = (width  + 3) >> 2;
  560       unsigned int h = (height + 3) >> 2;
  561 
  562       switch(GETL32(hdr->pixelfmt.fourcc))
  563       {
  564          case CHAR32('D', 'X', 'T', '1'): format = DDS_COMPRESS_BC1; break;
  565          case CHAR32('D', 'X', 'T', '3'): format = DDS_COMPRESS_BC2; break;
  566          case CHAR32('D', 'X', 'T', '5'): format = DDS_COMPRESS_BC3; break;
  567          case CHAR32('A', 'T', 'I', '1'): format = DDS_COMPRESS_BC4; break;
  568          case CHAR32('A', 'T', 'I', '2'): format = DDS_COMPRESS_BC5; break;
  569       }
  570 
  571       if(w == 0) w = 1;
  572       if(h == 0) h = 1;
  573       size = w * h;
  574       if(format == DDS_COMPRESS_BC1 || format == DDS_COMPRESS_BC4)
  575          size *= 8;
  576       else
  577          size *= 16;
  578    }
  579 
  580    if((hdr->flags & DDSD_LINEARSIZE) &&
  581       !fread(buf, size, 1, fp))
  582    {
  583       g_message("Unexpected EOF.\n");
  584       return(0);
  585    }
  586 
  587    if(hdr->pixelfmt.flags & DDPF_RGB)
  588    {
  589       z = 0;
  590       for(y = 0, n = 0; y < height; ++y, ++n)
  591       {
  592          if(n >= d->tile_height)
  593          {
  594             gimp_pixel_rgn_set_rect(&pixel_region, pixels, 0, y - n,
  595                                     drawable->width, n);
  596             n = 0;
  597             if(interactive_dds)
  598                gimp_progress_update((double)y / (double)hdr->height);
  599          }
  600 
  601          if((hdr->flags & DDSD_PITCH) &&
  602             !fread(buf, width * d->bpp, 1, fp))
  603          {
  604             g_message("Unexpected EOF.\n");
  605             return(0);
  606          }
  607 
  608          if(!(hdr->flags & DDSD_LINEARSIZE)) z = 0;
  609 
  610          for(x = 0; x < drawable->width; ++x)
  611          {
  612             unsigned int pixel = buf[z];
  613             unsigned int pos = (n * drawable->width + x) * d->gimp_bpp;
  614 
  615             if(d->bpp > 1) pixel += ((unsigned int)buf[z + 1] <<  8);
  616             if(d->bpp > 2) pixel += ((unsigned int)buf[z + 2] << 16);
  617             if(d->bpp > 3) pixel += ((unsigned int)buf[z + 3] << 24);
  618 
  619             if(d->bpp >= 3)
  620             {
  621                if(hdr->pixelfmt.amask == 0xc0000000) // handle RGB10A2
  622                {
  623                   pixels[pos + 0] = (pixel >> d->rshift) >> 2;
  624                   pixels[pos + 1] = (pixel >> d->gshift) >> 2;
  625                   pixels[pos + 2] = (pixel >> d->bshift) >> 2;
  626                   if(hdr->pixelfmt.flags & DDPF_ALPHAPIXELS)
  627                      pixels[pos + 3] = (pixel >> d->ashift << (8 - d->abits) & d->amask) * 255 / d->amask;
  628                }
  629                else
  630                {
  631                   pixels[pos] =
  632                      (pixel >> d->rshift << (8 - d->rbits) & d->rmask) * 255 / d->rmask;
  633                   pixels[pos + 1] =
  634                      (pixel >> d->gshift << (8 - d->gbits) & d->gmask) * 255 / d->gmask;
  635                   pixels[pos + 2] =
  636                      (pixel >> d->bshift << (8 - d->bbits) & d->bmask) * 255 / d->bmask;
  637                   if(hdr->pixelfmt.flags & DDPF_ALPHAPIXELS)
  638                   {
  639                      pixels[pos + 3] =
  640                         (pixel >> d->ashift << (8 - d->abits) & d->amask) * 255 / d->amask;
  641                   }
  642                }
  643             }
  644             else if(d->bpp == 2)
  645             {
  646                if(hdr->pixelfmt.amask == 0xf000) //RGBA4
  647                {
  648                   pixels[pos] =
  649                      (pixel >> d->rshift << (8 - d->rbits) & d->rmask) * 255 / d->rmask;
  650                   pixels[pos + 1] =
  651                      (pixel >> d->gshift << (8 - d->gbits) & d->gmask) * 255 / d->gmask;
  652                   pixels[pos + 2] =
  653                      (pixel >> d->bshift << (8 - d->bbits) & d->bmask) * 255 / d->bmask;
  654                   pixels[pos + 3] =
  655                      (pixel >> d->ashift << (8 - d->abits) & d->amask) * 255 / d->amask;
  656                }
  657                else if(hdr->pixelfmt.amask == 0xff00) //L8A8
  658                {
  659                   pixels[pos] =
  660                      (pixel >> d->rshift << (8 - d->rbits) & d->rmask) * 255 / d->rmask;
  661                   pixels[pos + 1] =
  662                      (pixel >> d->ashift << (8 - d->abits) & d->amask) * 255 / d->amask;
  663                }
  664                else if(hdr->pixelfmt.bmask == 0x1f) //R5G6B5 or RGB5A1
  665                {
  666                   pixels[pos] =
  667                      (pixel >> d->rshift << (8 - d->rbits) & d->rmask) * 255 / d->rmask;
  668                   pixels[pos + 1] =
  669                      (pixel >> d->gshift << (8 - d->gbits) & d->gmask) * 255 / d->gmask;
  670                   pixels[pos + 2] =
  671                      (pixel >> d->bshift << (8 - d->bbits) & d->bmask) * 255 / d->bmask;
  672                   if(hdr->pixelfmt.amask == 0x8000)
  673                   {
  674                      pixels[pos + 3] =
  675                          (pixel >> d->ashift << (8 - d->abits) & d->amask) * 255 / d->amask;
  676                   }
  677                }
  678                else //L16
  679                   pixels[pos] = (unsigned char)(255 * ((float)(pixel & 0xffff) / 65535.0f));
  680             }
  681             else
  682             {
  683                if(hdr->pixelfmt.flags & DDPF_PALETTEINDEXED8)
  684                {
  685                   pixels[pos] = pixel;
  686                }
  687                else if(hdr->pixelfmt.rmask == 0xe0) // R3G3B2
  688                {
  689                   pixels[pos] =
  690                      (pixel >> d->rshift << (8 - d->rbits) & d->rmask) * 255 / d->rmask;
  691                   pixels[pos + 1] =
  692                      (pixel >> d->gshift << (8 - d->gbits) & d->gmask) * 255 / d->gmask;
  693                   pixels[pos + 2] =
  694                      (pixel >> d->bshift << (8 - d->bbits) & d->bmask) * 255 / d->bmask;
  695                }
  696                else
  697                {
  698                   pixels[pos] =
  699                      (pixel >> d->rshift << (8 - d->rbits) & d->rmask) * 255 / d->rmask;
  700                }
  701             }
  702 
  703             z += d->bpp;
  704          }
  705       }
  706 
  707       gimp_pixel_rgn_set_rect(&pixel_region, pixels, 0, y - n,
  708                               drawable->width, n);
  709    }
  710    else if(hdr->pixelfmt.flags & DDPF_FOURCC)
  711    {
  712       unsigned char *dst;
  713 
  714       if(!(hdr->flags & DDSD_LINEARSIZE))
  715       {
  716          g_message("Image marked as compressed, but DDSD_LINEARSIZE is not set.\n");
  717          return(0);
  718       }
  719 
  720       dst = g_malloc(width * height * d->gimp_bpp);
  721       memset(dst, 0, width * height * d->gimp_bpp);
  722 
  723       if(d->gimp_bpp == 4)
  724       {
  725         for(y = 0; y < height; ++y)
  726             for(x = 0; x < width; ++x)
  727                dst[y * (width * 4) + x + 3] = 255;
  728       }
  729 
  730       dxt_decompress(dst, buf, format, size, width, height, d->gimp_bpp);
  731 
  732       z = 0;
  733       for(y = 0, n = 0; y < height; ++y, ++n)
  734       {
  735          if(n >= d->tile_height)
  736          {
  737             gimp_pixel_rgn_set_rect(&pixel_region, pixels, 0, y - n,
  738                                     drawable->width, n);
  739             n = 0;
  740             if(interactive_dds)
  741                gimp_progress_update((double)y / (double)hdr->height);
  742          }
  743 
  744          memcpy(pixels + n * drawable->width * d->gimp_bpp,
  745                 dst + y * drawable->width * d->gimp_bpp,
  746                 width * d->gimp_bpp);
  747       }
  748 
  749       gimp_pixel_rgn_set_rect(&pixel_region, pixels, 0, y - n,
  750                               drawable->width, n);
  751 
  752       g_free(dst);
  753    }
  754 
  755    gimp_drawable_flush(drawable);
  756    gimp_drawable_detach(drawable);
  757 
  758    return(1);
  759 }
  760 
  761 static int load_mipmaps(FILE *fp, dds_header_t *hdr, dds_load_info_t *d,
  762                         gint32 image, char *prefix, unsigned int *l,
  763                         guchar *pixels, unsigned char *buf)
  764 {
  765    unsigned int level;
  766 
  767    if((hdr->flags & DDSD_MIPMAPCOUNT) &&
  768       (hdr->caps.caps1 & DDSCAPS_MIPMAP))
  769    {
  770       for(level = 1; level < hdr->num_mipmaps; ++level)
  771       {
  772          if(!load_layer(fp, hdr, d, image, level, prefix, l, pixels, buf))
  773             return(0);
  774       }
  775    }
  776    return(1);
  777 }
  778 
  779 static int load_face(FILE *fp, dds_header_t *hdr, dds_load_info_t *d,
  780                      gint32 image, char *prefix, unsigned int *l,
  781                      guchar *pixels, unsigned char *buf)
  782 {
  783    if(!load_layer(fp, hdr, d, image, 0, prefix, l, pixels, buf))
  784       return(0);
  785    return(load_mipmaps(fp, hdr, d, image, prefix, l, pixels, buf));
  786 }
  787 
  788 static unsigned char color_bits(unsigned int mask)
  789 {
  790    unsigned char i = 0;
  791 
  792    while(mask)
  793    {
  794       if(mask & 1) ++i;
  795       mask >>= 1;
  796    }
  797    return(i);
  798 }
  799 
  800 static unsigned char color_shift(unsigned int mask)
  801 {
  802    unsigned char i = 0;
  803 
  804    if(!mask) return(0);
  805    while(!((mask >> i) & 1)) ++i;
  806    return(i);
  807 }

ViewVC Help
Powered by ViewVC 1.0.4