Parent Directory
|
Revision Log
Release 2.0.2 tag
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 /* test alpha only image */ 195 if(d.bpp == 1 && (hdr.pixelfmt.flags & DDPF_ALPHA)) 196 { 197 d.gimp_bpp = 2; 198 type = GIMP_GRAY; 199 } 200 else 201 { 202 d.gimp_bpp = d.bpp; 203 type = (d.bpp == 1) ? GIMP_GRAY : GIMP_RGB; 204 } 205 } 206 } 207 } 208 209 image = gimp_image_new(hdr.width, hdr.height, type); 210 211 if(image == -1) 212 { 213 g_message("Can't allocate new image.\n"); 214 fclose(fp); 215 return(-1); 216 } 217 218 gimp_image_set_filename(image, filename); 219 220 if(hdr.pixelfmt.flags & DDPF_PALETTEINDEXED8) 221 { 222 d.palette = g_malloc(256 * 4); 223 fread(d.palette, 1, 256 * 4, fp); 224 for(i = j = 0; i < 768; i += 3, j += 4) 225 { 226 d.palette[i + 0] = d.palette[j + 0]; 227 d.palette[i + 1] = d.palette[j + 1]; 228 d.palette[i + 2] = d.palette[j + 2]; 229 } 230 gimp_image_set_colormap(image, d.palette, 256); 231 } 232 233 d.tile_height = gimp_tile_height(); 234 235 pixels = g_new(guchar, d.tile_height * hdr.width * d.gimp_bpp); 236 buf = g_malloc(hdr.pitch_or_linsize); 237 238 d.rshift = color_shift(hdr.pixelfmt.rmask); 239 d.gshift = color_shift(hdr.pixelfmt.gmask); 240 d.bshift = color_shift(hdr.pixelfmt.bmask); 241 d.ashift = color_shift(hdr.pixelfmt.amask); 242 d.rbits = color_bits(hdr.pixelfmt.rmask); 243 d.gbits = color_bits(hdr.pixelfmt.gmask); 244 d.bbits = color_bits(hdr.pixelfmt.bmask); 245 d.abits = color_bits(hdr.pixelfmt.amask); 246 d.rmask = hdr.pixelfmt.rmask >> d.rshift << (8 - d.rbits); 247 d.gmask = hdr.pixelfmt.gmask >> d.gshift << (8 - d.gbits); 248 d.bmask = hdr.pixelfmt.bmask >> d.bshift << (8 - d.bbits); 249 d.amask = hdr.pixelfmt.amask >> d.ashift << (8 - d.abits); 250 251 if(!(hdr.caps.caps2 & DDSCAPS2_CUBEMAP) && 252 !(hdr.caps.caps2 & DDSCAPS2_VOLUME)) 253 { 254 if(!load_layer(fp, &hdr, &d, image, 0, "", &l, pixels, buf)) 255 { 256 fclose(fp); 257 gimp_image_delete(image); 258 return(-1); 259 } 260 } 261 262 if(hdr.caps.caps1 & DDSCAPS_COMPLEX) 263 { 264 if(hdr.caps.caps2 & DDSCAPS2_CUBEMAP) 265 { 266 if((hdr.caps.caps2 & DDSCAPS2_CUBEMAP_POSITIVEX) && 267 !load_face(fp, &hdr, &d, image, "(positive x)", &l, pixels, buf)) 268 { 269 fclose(fp); 270 gimp_image_delete(image); 271 return(-1); 272 } 273 if((hdr.caps.caps2 & DDSCAPS2_CUBEMAP_NEGATIVEX) && 274 !load_face(fp, &hdr, &d, image, "(negative x)", &l, pixels, buf)) 275 { 276 fclose(fp); 277 gimp_image_delete(image); 278 return(-1); 279 } 280 if((hdr.caps.caps2 & DDSCAPS2_CUBEMAP_POSITIVEY) && 281 !load_face(fp, &hdr, &d, image, "(positive y)", &l, pixels, buf)) 282 { 283 fclose(fp); 284 gimp_image_delete(image); 285 return(-1); 286 } 287 if((hdr.caps.caps2 & DDSCAPS2_CUBEMAP_NEGATIVEY) && 288 !load_face(fp, &hdr, &d, image, "(negative y)", &l, pixels, buf)) 289 { 290 fclose(fp); 291 gimp_image_delete(image); 292 return(-1); 293 } 294 if((hdr.caps.caps2 & DDSCAPS2_CUBEMAP_POSITIVEZ) && 295 !load_face(fp, &hdr, &d, image, "(positive z)", &l, pixels, buf)) 296 { 297 fclose(fp); 298 gimp_image_delete(image); 299 return(-1); 300 } 301 if((hdr.caps.caps2 & DDSCAPS2_CUBEMAP_NEGATIVEZ) && 302 !load_face(fp, &hdr, &d, image, "(negative z)", &l, pixels, buf)) 303 { 304 fclose(fp); 305 gimp_image_delete(image); 306 return(-1); 307 } 308 } 309 else if((hdr.caps.caps2 & DDSCAPS2_VOLUME) && 310 (hdr.flags & DDSD_DEPTH)) 311 { 312 unsigned int i, level; 313 char *plane; 314 for(i = 0; i < hdr.depth; ++i) 315 { 316 plane = g_strdup_printf("(z = %d)", i); 317 if(!load_layer(fp, &hdr, &d, image, 0, plane, &l, pixels, buf)) 318 { 319 g_free(plane); 320 fclose(fp); 321 gimp_image_delete(image); 322 return(-1); 323 } 324 g_free(plane); 325 } 326 327 if((hdr.flags & DDSD_MIPMAPCOUNT) && 328 (hdr.caps.caps1 & DDSCAPS_MIPMAP)) 329 { 330 for(level = 1; level < hdr.num_mipmaps; ++level) 331 { 332 int n = hdr.depth >> level; 333 if(n < 1) n = 1; 334 for(i = 0; i < n; ++i) 335 { 336 plane = g_strdup_printf("(z = %d)", i); 337 if(!load_layer(fp, &hdr, &d, image, level, plane, &l, pixels, buf)) 338 { 339 g_free(plane); 340 fclose(fp); 341 gimp_image_delete(image); 342 return(-1); 343 } 344 g_free(plane); 345 } 346 } 347 } 348 } 349 else if(!load_mipmaps(fp, &hdr, &d, image, "", &l, pixels, buf)) 350 { 351 fclose(fp); 352 gimp_image_delete(image); 353 return(-1); 354 } 355 } 356 357 if(hdr.pixelfmt.flags & DDPF_PALETTEINDEXED8) 358 g_free(d.palette); 359 360 g_free(buf); 361 g_free(pixels); 362 fclose(fp); 363 364 layers = gimp_image_get_layers(image, &layer_count); 365 gimp_image_set_active_layer(image, layers[0]); 366 367 return(image); 368 } 369 370 static int read_header(dds_header_t *hdr, FILE *fp) 371 { 372 unsigned char buf[DDS_HEADERSIZE]; 373 374 memset(hdr, 0, sizeof(dds_header_t)); 375 376 if(fread(buf, 1, DDS_HEADERSIZE, fp) != DDS_HEADERSIZE) 377 return(0); 378 379 hdr->magic[0] = buf[0]; 380 hdr->magic[1] = buf[1]; 381 hdr->magic[2] = buf[2]; 382 hdr->magic[3] = buf[3]; 383 384 hdr->size = GETL32(buf + 4); 385 hdr->flags = GETL32(buf + 8); 386 hdr->height = GETL32(buf + 12); 387 hdr->width = GETL32(buf + 16); 388 hdr->pitch_or_linsize = GETL32(buf + 20); 389 hdr->depth = GETL32(buf + 24); 390 hdr->num_mipmaps = GETL32(buf + 28); 391 392 hdr->pixelfmt.size = GETL32(buf + 76); 393 hdr->pixelfmt.flags = GETL32(buf + 80); 394 hdr->pixelfmt.fourcc[0] = buf[84]; 395 hdr->pixelfmt.fourcc[1] = buf[85]; 396 hdr->pixelfmt.fourcc[2] = buf[86]; 397 hdr->pixelfmt.fourcc[3] = buf[87]; 398 hdr->pixelfmt.bpp = GETL32(buf + 88); 399 hdr->pixelfmt.rmask = GETL32(buf + 92); 400 hdr->pixelfmt.gmask = GETL32(buf + 96); 401 hdr->pixelfmt.bmask = GETL32(buf + 100); 402 hdr->pixelfmt.amask = GETL32(buf + 104); 403 404 hdr->caps.caps1 = GETL32(buf + 108); 405 hdr->caps.caps2 = GETL32(buf + 112); 406 407 return(1); 408 } 409 410 static int validate_header(dds_header_t *hdr) 411 { 412 if(memcmp(hdr->magic, "DDS ", 4)) 413 { 414 g_message("Invalid DDS file.\n"); 415 return(0); 416 } 417 418 if((hdr->flags & DDSD_PITCH) == (hdr->flags & DDSD_LINEARSIZE)) 419 { 420 //g_message("Warning: DDSD_PITCH or DDSD_LINEARSIZE is not set.\n"); 421 if(hdr->pixelfmt.flags & DDPF_FOURCC) 422 hdr->flags |= DDSD_LINEARSIZE; 423 else 424 hdr->flags |= DDSD_PITCH; 425 } 426 /* 427 if((hdr->pixelfmt.flags & DDPF_FOURCC) == 428 (hdr->pixelfmt.flags & DDPF_RGB)) 429 { 430 g_message("Invalid pixel format.\n"); 431 return(0); 432 } 433 */ 434 if((hdr->pixelfmt.flags & DDPF_FOURCC) && 435 memcmp(hdr->pixelfmt.fourcc, "DXT1", 4) && 436 memcmp(hdr->pixelfmt.fourcc, "DXT3", 4) && 437 memcmp(hdr->pixelfmt.fourcc, "DXT5", 4) && 438 memcmp(hdr->pixelfmt.fourcc, "ATI1", 4) && 439 memcmp(hdr->pixelfmt.fourcc, "ATI2", 4)) 440 { 441 g_message("Invalid compression format.\n" 442 "Only DXT1, DXT3, DXT5, ATI1N and ATI2N formats are supported.\n"); 443 return(0); 444 } 445 446 if(hdr->pixelfmt.flags & DDPF_RGB) 447 { 448 if((hdr->pixelfmt.bpp != 8) && 449 (hdr->pixelfmt.bpp != 16) && 450 (hdr->pixelfmt.bpp != 24) && 451 (hdr->pixelfmt.bpp != 32)) 452 { 453 g_message("Invalid BPP.\n"); 454 return(0); 455 } 456 } 457 else if(hdr->pixelfmt.flags & DDPF_LUMINANCE) 458 { 459 if((hdr->pixelfmt.bpp != 8) && 460 (hdr->pixelfmt.bpp != 16)) 461 { 462 g_message("Invalid BPP.\n"); 463 return(0); 464 } 465 466 hdr->pixelfmt.flags |= DDPF_RGB; 467 } 468 else if(hdr->pixelfmt.flags & DDPF_PALETTEINDEXED8) 469 { 470 hdr->pixelfmt.flags |= DDPF_RGB; 471 } 472 473 if(!(hdr->pixelfmt.flags & DDPF_RGB) && 474 !(hdr->pixelfmt.flags & DDPF_ALPHA) && 475 !(hdr->pixelfmt.flags & DDPF_FOURCC) && 476 !(hdr->pixelfmt.flags & DDPF_LUMINANCE)) 477 { 478 g_message("Unknown pixel format! Taking a guess, expect trouble!"); 479 switch(GETL32(hdr->pixelfmt.fourcc)) 480 { 481 case CHAR32('D', 'X', 'T', '1'): 482 case CHAR32('D', 'X', 'T', '3'): 483 case CHAR32('D', 'X', 'T', '5'): 484 case CHAR32('A', 'T', 'I', '1'): 485 case CHAR32('A', 'T', 'I', '2'): 486 hdr->pixelfmt.flags |= DDPF_FOURCC; 487 break; 488 default: 489 switch(hdr->pixelfmt.bpp) 490 { 491 case 8: 492 if(hdr->pixelfmt.flags & DDPF_ALPHAPIXELS) 493 hdr->pixelfmt.flags |= DDPF_ALPHA; 494 else 495 hdr->pixelfmt.flags |= DDPF_LUMINANCE; 496 break; 497 case 16: 498 case 24: 499 case 32: 500 hdr->pixelfmt.flags |= DDPF_RGB; 501 break; 502 default: 503 g_message("Invalid pixel format."); 504 return(0); 505 } 506 break; 507 } 508 } 509 510 return(1); 511 } 512 513 static int load_layer(FILE *fp, dds_header_t *hdr, dds_load_info_t *d, 514 gint32 image, unsigned int level, char *prefix, 515 unsigned int *l, guchar *pixels, unsigned char *buf) 516 { 517 GimpDrawable *drawable; 518 GimpPixelRgn pixel_region; 519 GimpImageType type = GIMP_RGBA_IMAGE; 520 gchar *layer_name; 521 gint x, y, z, n; 522 gint32 layer; 523 unsigned int width = hdr->width >> level; 524 unsigned int height = hdr->height >> level; 525 unsigned int size = hdr->pitch_or_linsize >> (2 * level); 526 int format = DDS_COMPRESS_NONE; 527 528 if(width < 1) width = 1; 529 if(height < 1) height = 1; 530 531 switch(d->bpp) 532 { 533 case 1: 534 if(hdr->pixelfmt.flags & DDPF_PALETTEINDEXED8) 535 type = GIMP_INDEXED_IMAGE; 536 else if(hdr->pixelfmt.rmask == 0xe0) 537 type = GIMP_RGB_IMAGE; 538 else if(hdr->pixelfmt.flags & DDPF_ALPHA) 539 type = GIMP_GRAYA_IMAGE; 540 else 541 type = GIMP_GRAY_IMAGE; 542 break; 543 case 2: 544 if(hdr->pixelfmt.amask == 0xf000) //RGBA4 545 type = GIMP_RGBA_IMAGE; 546 else if(hdr->pixelfmt.amask == 0xff00) //L8A8 547 type = GIMP_GRAYA_IMAGE; 548 else if(hdr->pixelfmt.bmask == 0x1f) //R5G6B5 or RGB5A1 549 type = (hdr->pixelfmt.amask == 0x8000) ? GIMP_RGBA_IMAGE : GIMP_RGB_IMAGE; 550 else //L16 551 type = GIMP_GRAY_IMAGE; 552 break; 553 case 3: type = GIMP_RGB_IMAGE; break; 554 case 4: type = GIMP_RGBA_IMAGE; break; 555 } 556 557 layer_name = (level) ? g_strdup_printf("mipmap %d %s", level, prefix) : 558 g_strdup_printf("main surface %s", prefix); 559 560 layer = gimp_layer_new(image, layer_name, width, height, type, 100, 561 GIMP_NORMAL_MODE); 562 g_free(layer_name); 563 564 gimp_image_add_layer(image, layer, *l); 565 if((*l)++) gimp_drawable_set_visible(layer, FALSE); 566 567 drawable = gimp_drawable_get(layer); 568 569 gimp_pixel_rgn_init(&pixel_region, drawable, 0, 0, drawable->width, 570 drawable->height, TRUE, FALSE); 571 572 if(hdr->pixelfmt.flags & DDPF_FOURCC) 573 { 574 unsigned int w = (width + 3) >> 2; 575 unsigned int h = (height + 3) >> 2; 576 577 switch(GETL32(hdr->pixelfmt.fourcc)) 578 { 579 case CHAR32('D', 'X', 'T', '1'): format = DDS_COMPRESS_BC1; break; 580 case CHAR32('D', 'X', 'T', '3'): format = DDS_COMPRESS_BC2; break; 581 case CHAR32('D', 'X', 'T', '5'): format = DDS_COMPRESS_BC3; break; 582 case CHAR32('A', 'T', 'I', '1'): format = DDS_COMPRESS_BC4; break; 583 case CHAR32('A', 'T', 'I', '2'): format = DDS_COMPRESS_BC5; break; 584 } 585 586 if(w == 0) w = 1; 587 if(h == 0) h = 1; 588 size = w * h; 589 if(format == DDS_COMPRESS_BC1 || format == DDS_COMPRESS_BC4) 590 size *= 8; 591 else 592 size *= 16; 593 } 594 595 if((hdr->flags & DDSD_LINEARSIZE) && 596 !fread(buf, size, 1, fp)) 597 { 598 g_message("Unexpected EOF.\n"); 599 return(0); 600 } 601 602 if(hdr->pixelfmt.flags & DDPF_RGB || hdr->pixelfmt.flags & DDPF_ALPHA) 603 { 604 z = 0; 605 for(y = 0, n = 0; y < height; ++y, ++n) 606 { 607 if(n >= d->tile_height) 608 { 609 gimp_pixel_rgn_set_rect(&pixel_region, pixels, 0, y - n, 610 drawable->width, n); 611 n = 0; 612 if(interactive_dds) 613 gimp_progress_update((double)y / (double)hdr->height); 614 } 615 616 if((hdr->flags & DDSD_PITCH) && 617 !fread(buf, width * d->bpp, 1, fp)) 618 { 619 g_message("Unexpected EOF.\n"); 620 return(0); 621 } 622 623 if(!(hdr->flags & DDSD_LINEARSIZE)) z = 0; 624 625 for(x = 0; x < drawable->width; ++x) 626 { 627 unsigned int pixel = buf[z]; 628 unsigned int pos = (n * drawable->width + x) * d->gimp_bpp; 629 630 if(d->bpp > 1) pixel += ((unsigned int)buf[z + 1] << 8); 631 if(d->bpp > 2) pixel += ((unsigned int)buf[z + 2] << 16); 632 if(d->bpp > 3) pixel += ((unsigned int)buf[z + 3] << 24); 633 634 if(d->bpp >= 3) 635 { 636 if(hdr->pixelfmt.amask == 0xc0000000) // handle RGB10A2 637 { 638 pixels[pos + 0] = (pixel >> d->rshift) >> 2; 639 pixels[pos + 1] = (pixel >> d->gshift) >> 2; 640 pixels[pos + 2] = (pixel >> d->bshift) >> 2; 641 if(hdr->pixelfmt.flags & DDPF_ALPHAPIXELS) 642 pixels[pos + 3] = (pixel >> d->ashift << (8 - d->abits) & d->amask) * 255 / d->amask; 643 } 644 else 645 { 646 pixels[pos] = 647 (pixel >> d->rshift << (8 - d->rbits) & d->rmask) * 255 / d->rmask; 648 pixels[pos + 1] = 649 (pixel >> d->gshift << (8 - d->gbits) & d->gmask) * 255 / d->gmask; 650 pixels[pos + 2] = 651 (pixel >> d->bshift << (8 - d->bbits) & d->bmask) * 255 / d->bmask; 652 if(hdr->pixelfmt.flags & DDPF_ALPHAPIXELS) 653 { 654 pixels[pos + 3] = 655 (pixel >> d->ashift << (8 - d->abits) & d->amask) * 255 / d->amask; 656 } 657 } 658 } 659 else if(d->bpp == 2) 660 { 661 if(hdr->pixelfmt.amask == 0xf000) //RGBA4 662 { 663 pixels[pos] = 664 (pixel >> d->rshift << (8 - d->rbits) & d->rmask) * 255 / d->rmask; 665 pixels[pos + 1] = 666 (pixel >> d->gshift << (8 - d->gbits) & d->gmask) * 255 / d->gmask; 667 pixels[pos + 2] = 668 (pixel >> d->bshift << (8 - d->bbits) & d->bmask) * 255 / d->bmask; 669 pixels[pos + 3] = 670 (pixel >> d->ashift << (8 - d->abits) & d->amask) * 255 / d->amask; 671 } 672 else if(hdr->pixelfmt.amask == 0xff00) //L8A8 673 { 674 pixels[pos] = 675 (pixel >> d->rshift << (8 - d->rbits) & d->rmask) * 255 / d->rmask; 676 pixels[pos + 1] = 677 (pixel >> d->ashift << (8 - d->abits) & d->amask) * 255 / d->amask; 678 } 679 else if(hdr->pixelfmt.bmask == 0x1f) //R5G6B5 or RGB5A1 680 { 681 pixels[pos] = 682 (pixel >> d->rshift << (8 - d->rbits) & d->rmask) * 255 / d->rmask; 683 pixels[pos + 1] = 684 (pixel >> d->gshift << (8 - d->gbits) & d->gmask) * 255 / d->gmask; 685 pixels[pos + 2] = 686 (pixel >> d->bshift << (8 - d->bbits) & d->bmask) * 255 / d->bmask; 687 if(hdr->pixelfmt.amask == 0x8000) 688 { 689 pixels[pos + 3] = 690 (pixel >> d->ashift << (8 - d->abits) & d->amask) * 255 / d->amask; 691 } 692 } 693 else //L16 694 pixels[pos] = (unsigned char)(255 * ((float)(pixel & 0xffff) / 65535.0f)); 695 } 696 else 697 { 698 if(hdr->pixelfmt.flags & DDPF_PALETTEINDEXED8) 699 { 700 pixels[pos] = pixel & 0xff; 701 } 702 else if(hdr->pixelfmt.rmask == 0xe0) // R3G3B2 703 { 704 pixels[pos] = 705 (pixel >> d->rshift << (8 - d->rbits) & d->rmask) * 255 / d->rmask; 706 pixels[pos + 1] = 707 (pixel >> d->gshift << (8 - d->gbits) & d->gmask) * 255 / d->gmask; 708 pixels[pos + 2] = 709 (pixel >> d->bshift << (8 - d->bbits) & d->bmask) * 255 / d->bmask; 710 } 711 else if(hdr->pixelfmt.flags & DDPF_ALPHA) 712 { 713 pixels[pos + 0] = 255; 714 pixels[pos + 1] = pixel & 0xff; 715 } 716 else // LUMINANCE 717 { 718 pixels[pos] = pixel & 0xff; 719 } 720 } 721 722 z += d->bpp; 723 } 724 } 725 726 gimp_pixel_rgn_set_rect(&pixel_region, pixels, 0, y - n, 727 drawable->width, n); 728 } 729 else if(hdr->pixelfmt.flags & DDPF_FOURCC) 730 { 731 unsigned char *dst; 732 733 if(!(hdr->flags & DDSD_LINEARSIZE)) 734 { 735 g_message("Image marked as compressed, but DDSD_LINEARSIZE is not set.\n"); 736 return(0); 737 } 738 739 dst = g_malloc(width * height * d->gimp_bpp); 740 memset(dst, 0, width * height * d->gimp_bpp); 741 742 if(d->gimp_bpp == 4) 743 { 744 for(y = 0; y < height; ++y) 745 for(x = 0; x < width; ++x) 746 dst[y * (width * 4) + x + 3] = 255; 747 } 748 749 dxt_decompress(dst, buf, format, size, width, height, d->gimp_bpp); 750 751 z = 0; 752 for(y = 0, n = 0; y < height; ++y, ++n) 753 { 754 if(n >= d->tile_height) 755 { 756 gimp_pixel_rgn_set_rect(&pixel_region, pixels, 0, y - n, 757 drawable->width, n); 758 n = 0; 759 if(interactive_dds) 760 gimp_progress_update((double)y / (double)hdr->height); 761 } 762 763 memcpy(pixels + n * drawable->width * d->gimp_bpp, 764 dst + y * drawable->width * d->gimp_bpp, 765 width * d->gimp_bpp); 766 } 767 768 gimp_pixel_rgn_set_rect(&pixel_region, pixels, 0, y - n, 769 drawable->width, n); 770 771 g_free(dst); 772 } 773 774 gimp_drawable_flush(drawable); 775 gimp_drawable_detach(drawable); 776 777 return(1); 778 } 779 780 static int load_mipmaps(FILE *fp, dds_header_t *hdr, dds_load_info_t *d, 781 gint32 image, char *prefix, unsigned int *l, 782 guchar *pixels, unsigned char *buf) 783 { 784 unsigned int level; 785 786 if((hdr->flags & DDSD_MIPMAPCOUNT) && 787 (hdr->caps.caps1 & DDSCAPS_MIPMAP)) 788 { 789 for(level = 1; level < hdr->num_mipmaps; ++level) 790 { 791 if(!load_layer(fp, hdr, d, image, level, prefix, l, pixels, buf)) 792 return(0); 793 } 794 } 795 return(1); 796 } 797 798 static int load_face(FILE *fp, dds_header_t *hdr, dds_load_info_t *d, 799 gint32 image, char *prefix, unsigned int *l, 800 guchar *pixels, unsigned char *buf) 801 { 802 if(!load_layer(fp, hdr, d, image, 0, prefix, l, pixels, buf)) 803 return(0); 804 return(load_mipmaps(fp, hdr, d, image, prefix, l, pixels, buf)); 805 } 806 807 static unsigned char color_bits(unsigned int mask) 808 { 809 unsigned char i = 0; 810 811 while(mask) 812 { 813 if(mask & 1) ++i; 814 mask >>= 1; 815 } 816 return(i); 817 } 818 819 static unsigned char color_shift(unsigned int mask) 820 { 821 unsigned char i = 0; 822 823 if(!mask) return(0); 824 while(!((mask >> i) & 1)) ++i; 825 return(i); 826 }
| ViewVC Help | |
| Powered by ViewVC 1.0.4 |