Parent Directory
|
Revision Log
Release 2.0.3 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 /* 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 static int load_dialog(void); 69 70 static int runme = 0; 71 72 GimpPDBStatusType read_dds(gchar *filename, gint32 *imageID) 73 { 74 gint32 image = 0; 75 unsigned char *buf; 76 unsigned int l = 0; 77 guchar *pixels; 78 gchar *tmp; 79 FILE *fp; 80 dds_header_t hdr; 81 dds_load_info_t d; 82 gint *layers, layer_count; 83 GimpImageBaseType type; 84 int i, j; 85 86 if(interactive_dds && dds_read_vals.show_dialog) 87 { 88 if(!load_dialog()) 89 return(GIMP_PDB_CANCEL); 90 } 91 92 fp = fopen(filename, "rb"); 93 if(fp == 0) 94 { 95 g_message("Error opening file.\n"); 96 return(GIMP_PDB_EXECUTION_ERROR); 97 } 98 99 if(interactive_dds) 100 { 101 if(strrchr(filename, '/')) 102 tmp = g_strdup_printf("Loading %s:", strrchr(filename, '/') + 1); 103 else 104 tmp = g_strdup_printf("Loading %s:", filename); 105 gimp_progress_init(tmp); 106 g_free(tmp); 107 } 108 109 read_header(&hdr, fp); 110 if(!validate_header(&hdr)) 111 { 112 fclose(fp); 113 g_message("Invalid DDS header!\n"); 114 return(GIMP_PDB_EXECUTION_ERROR); 115 } 116 117 /* a lot of DDS images out there don't have this for some reason -_- */ 118 if(hdr.pitch_or_linsize == 0) 119 { 120 if(hdr.pixelfmt.flags & DDPF_FOURCC) /* assume linear size */ 121 { 122 hdr.pitch_or_linsize = ((hdr.width + 3) >> 2) * ((hdr.height + 3) >> 2); 123 if(hdr.pixelfmt.fourcc[3] == '1') 124 hdr.pitch_or_linsize *= 8; 125 else 126 hdr.pitch_or_linsize *= 16; 127 } 128 else /* assume pitch */ 129 { 130 hdr.pitch_or_linsize = hdr.height * hdr.width * 131 (hdr.pixelfmt.bpp >> 3); 132 } 133 } 134 135 if(hdr.pixelfmt.flags & DDPF_FOURCC) 136 { 137 if(hdr.pixelfmt.fourcc[0] == 'D') 138 hdr.pixelfmt.flags |= DDPF_ALPHAPIXELS; 139 } 140 141 if(hdr.pixelfmt.flags & DDPF_FOURCC) 142 { 143 switch(GETL32(hdr.pixelfmt.fourcc)) 144 { 145 case CHAR32('A', 'T', 'I', '1'): 146 d.bpp = d.gimp_bpp = 1; 147 type = GIMP_GRAY; 148 break; 149 case CHAR32('A', 'T', 'I', '2'): 150 d.bpp = d.gimp_bpp = 3; 151 type = GIMP_RGB; 152 break; 153 default: 154 d.bpp = d.gimp_bpp = 4; 155 type = GIMP_RGB; 156 break; 157 } 158 } 159 else 160 { 161 d.bpp = hdr.pixelfmt.bpp >> 3; 162 163 if(d.bpp == 2) 164 { 165 if(hdr.pixelfmt.amask == 0xf000) // RGBA4 166 { 167 d.gimp_bpp = 4; 168 type = GIMP_RGB; 169 } 170 else if(hdr.pixelfmt.amask == 0xff00) //L8A8 171 { 172 d.gimp_bpp = 2; 173 type = GIMP_GRAY; 174 } 175 else if(hdr.pixelfmt.bmask == 0x1f) //R5G6B5 or RGB5A1 176 { 177 if(hdr.pixelfmt.amask == 0x8000) // RGB5A1 178 d.gimp_bpp = 4; 179 else 180 d.gimp_bpp = 3; 181 182 type = GIMP_RGB; 183 } 184 else //L16 185 { 186 d.gimp_bpp = 1; 187 type = GIMP_GRAY; 188 } 189 } 190 else 191 { 192 if(hdr.pixelfmt.flags & DDPF_PALETTEINDEXED8) 193 { 194 type = GIMP_INDEXED; 195 d.gimp_bpp = 1; 196 } 197 else if(hdr.pixelfmt.rmask == 0xe0) // R3G3B2 198 { 199 type = GIMP_RGB; 200 d.gimp_bpp = 3; 201 } 202 else 203 { 204 /* test alpha only image */ 205 if(d.bpp == 1 && (hdr.pixelfmt.flags & DDPF_ALPHA)) 206 { 207 d.gimp_bpp = 2; 208 type = GIMP_GRAY; 209 } 210 else 211 { 212 d.gimp_bpp = d.bpp; 213 type = (d.bpp == 1) ? GIMP_GRAY : GIMP_RGB; 214 } 215 } 216 } 217 } 218 219 image = gimp_image_new(hdr.width, hdr.height, type); 220 221 if(image == -1) 222 { 223 g_message("Can't allocate new image.\n"); 224 fclose(fp); 225 return(GIMP_PDB_EXECUTION_ERROR); 226 } 227 228 gimp_image_set_filename(image, filename); 229 230 if(hdr.pixelfmt.flags & DDPF_PALETTEINDEXED8) 231 { 232 d.palette = g_malloc(256 * 4); 233 fread(d.palette, 1, 256 * 4, fp); 234 for(i = j = 0; i < 768; i += 3, j += 4) 235 { 236 d.palette[i + 0] = d.palette[j + 0]; 237 d.palette[i + 1] = d.palette[j + 1]; 238 d.palette[i + 2] = d.palette[j + 2]; 239 } 240 gimp_image_set_colormap(image, d.palette, 256); 241 } 242 243 d.tile_height = gimp_tile_height(); 244 245 pixels = g_new(guchar, d.tile_height * hdr.width * d.gimp_bpp); 246 buf = g_malloc(hdr.pitch_or_linsize); 247 248 d.rshift = color_shift(hdr.pixelfmt.rmask); 249 d.gshift = color_shift(hdr.pixelfmt.gmask); 250 d.bshift = color_shift(hdr.pixelfmt.bmask); 251 d.ashift = color_shift(hdr.pixelfmt.amask); 252 d.rbits = color_bits(hdr.pixelfmt.rmask); 253 d.gbits = color_bits(hdr.pixelfmt.gmask); 254 d.bbits = color_bits(hdr.pixelfmt.bmask); 255 d.abits = color_bits(hdr.pixelfmt.amask); 256 d.rmask = hdr.pixelfmt.rmask >> d.rshift << (8 - d.rbits); 257 d.gmask = hdr.pixelfmt.gmask >> d.gshift << (8 - d.gbits); 258 d.bmask = hdr.pixelfmt.bmask >> d.bshift << (8 - d.bbits); 259 d.amask = hdr.pixelfmt.amask >> d.ashift << (8 - d.abits); 260 261 if(!(hdr.caps.caps2 & DDSCAPS2_CUBEMAP) && 262 !(hdr.caps.caps2 & DDSCAPS2_VOLUME)) 263 { 264 if(!load_layer(fp, &hdr, &d, image, 0, "", &l, pixels, buf)) 265 { 266 fclose(fp); 267 gimp_image_delete(image); 268 return(GIMP_PDB_EXECUTION_ERROR); 269 } 270 } 271 272 if(hdr.caps.caps1 & DDSCAPS_COMPLEX) 273 { 274 if(hdr.caps.caps2 & DDSCAPS2_CUBEMAP) 275 { 276 if((hdr.caps.caps2 & DDSCAPS2_CUBEMAP_POSITIVEX) && 277 !load_face(fp, &hdr, &d, image, "(positive x)", &l, pixels, buf)) 278 { 279 fclose(fp); 280 gimp_image_delete(image); 281 return(GIMP_PDB_EXECUTION_ERROR); 282 } 283 if((hdr.caps.caps2 & DDSCAPS2_CUBEMAP_NEGATIVEX) && 284 !load_face(fp, &hdr, &d, image, "(negative x)", &l, pixels, buf)) 285 { 286 fclose(fp); 287 gimp_image_delete(image); 288 return(GIMP_PDB_EXECUTION_ERROR); 289 } 290 if((hdr.caps.caps2 & DDSCAPS2_CUBEMAP_POSITIVEY) && 291 !load_face(fp, &hdr, &d, image, "(positive y)", &l, pixels, buf)) 292 { 293 fclose(fp); 294 gimp_image_delete(image); 295 return(GIMP_PDB_EXECUTION_ERROR); 296 } 297 if((hdr.caps.caps2 & DDSCAPS2_CUBEMAP_NEGATIVEY) && 298 !load_face(fp, &hdr, &d, image, "(negative y)", &l, pixels, buf)) 299 { 300 fclose(fp); 301 gimp_image_delete(image); 302 return(GIMP_PDB_EXECUTION_ERROR); 303 } 304 if((hdr.caps.caps2 & DDSCAPS2_CUBEMAP_POSITIVEZ) && 305 !load_face(fp, &hdr, &d, image, "(positive z)", &l, pixels, buf)) 306 { 307 fclose(fp); 308 gimp_image_delete(image); 309 return(GIMP_PDB_EXECUTION_ERROR); 310 } 311 if((hdr.caps.caps2 & DDSCAPS2_CUBEMAP_NEGATIVEZ) && 312 !load_face(fp, &hdr, &d, image, "(negative z)", &l, pixels, buf)) 313 { 314 fclose(fp); 315 gimp_image_delete(image); 316 return(GIMP_PDB_EXECUTION_ERROR); 317 } 318 } 319 else if((hdr.caps.caps2 & DDSCAPS2_VOLUME) && 320 (hdr.flags & DDSD_DEPTH)) 321 { 322 unsigned int i, level; 323 char *plane; 324 for(i = 0; i < hdr.depth; ++i) 325 { 326 plane = g_strdup_printf("(z = %d)", i); 327 if(!load_layer(fp, &hdr, &d, image, 0, plane, &l, pixels, buf)) 328 { 329 g_free(plane); 330 fclose(fp); 331 gimp_image_delete(image); 332 return(GIMP_PDB_EXECUTION_ERROR); 333 } 334 g_free(plane); 335 } 336 337 if((hdr.flags & DDSD_MIPMAPCOUNT) && 338 (hdr.caps.caps1 & DDSCAPS_MIPMAP) && 339 (dds_read_vals.mipmaps != 0)) 340 { 341 for(level = 1; level < hdr.num_mipmaps; ++level) 342 { 343 int n = hdr.depth >> level; 344 if(n < 1) n = 1; 345 for(i = 0; i < n; ++i) 346 { 347 plane = g_strdup_printf("(z = %d)", i); 348 if(!load_layer(fp, &hdr, &d, image, level, plane, &l, pixels, buf)) 349 { 350 g_free(plane); 351 fclose(fp); 352 gimp_image_delete(image); 353 return(GIMP_PDB_EXECUTION_ERROR); 354 } 355 g_free(plane); 356 } 357 } 358 } 359 } 360 else if(dds_read_vals.mipmaps) 361 { 362 if(!load_mipmaps(fp, &hdr, &d, image, "", &l, pixels, buf)) 363 { 364 fclose(fp); 365 gimp_image_delete(image); 366 return(GIMP_PDB_EXECUTION_ERROR); 367 } 368 } 369 } 370 371 if(hdr.pixelfmt.flags & DDPF_PALETTEINDEXED8) 372 g_free(d.palette); 373 374 g_free(buf); 375 g_free(pixels); 376 fclose(fp); 377 378 layers = gimp_image_get_layers(image, &layer_count); 379 gimp_image_set_active_layer(image, layers[0]); 380 381 *imageID = image; 382 383 return(GIMP_PDB_SUCCESS); 384 } 385 386 static int read_header(dds_header_t *hdr, FILE *fp) 387 { 388 unsigned char buf[DDS_HEADERSIZE]; 389 390 memset(hdr, 0, sizeof(dds_header_t)); 391 392 if(fread(buf, 1, DDS_HEADERSIZE, fp) != DDS_HEADERSIZE) 393 return(0); 394 395 hdr->magic[0] = buf[0]; 396 hdr->magic[1] = buf[1]; 397 hdr->magic[2] = buf[2]; 398 hdr->magic[3] = buf[3]; 399 400 hdr->size = GETL32(buf + 4); 401 hdr->flags = GETL32(buf + 8); 402 hdr->height = GETL32(buf + 12); 403 hdr->width = GETL32(buf + 16); 404 hdr->pitch_or_linsize = GETL32(buf + 20); 405 hdr->depth = GETL32(buf + 24); 406 hdr->num_mipmaps = GETL32(buf + 28); 407 408 hdr->pixelfmt.size = GETL32(buf + 76); 409 hdr->pixelfmt.flags = GETL32(buf + 80); 410 hdr->pixelfmt.fourcc[0] = buf[84]; 411 hdr->pixelfmt.fourcc[1] = buf[85]; 412 hdr->pixelfmt.fourcc[2] = buf[86]; 413 hdr->pixelfmt.fourcc[3] = buf[87]; 414 hdr->pixelfmt.bpp = GETL32(buf + 88); 415 hdr->pixelfmt.rmask = GETL32(buf + 92); 416 hdr->pixelfmt.gmask = GETL32(buf + 96); 417 hdr->pixelfmt.bmask = GETL32(buf + 100); 418 hdr->pixelfmt.amask = GETL32(buf + 104); 419 420 hdr->caps.caps1 = GETL32(buf + 108); 421 hdr->caps.caps2 = GETL32(buf + 112); 422 423 return(1); 424 } 425 426 static int validate_header(dds_header_t *hdr) 427 { 428 if(memcmp(hdr->magic, "DDS ", 4)) 429 { 430 g_message("Invalid DDS file.\n"); 431 return(0); 432 } 433 434 if((hdr->flags & DDSD_PITCH) == (hdr->flags & DDSD_LINEARSIZE)) 435 { 436 //g_message("Warning: DDSD_PITCH or DDSD_LINEARSIZE is not set.\n"); 437 if(hdr->pixelfmt.flags & DDPF_FOURCC) 438 hdr->flags |= DDSD_LINEARSIZE; 439 else 440 hdr->flags |= DDSD_PITCH; 441 } 442 /* 443 if((hdr->pixelfmt.flags & DDPF_FOURCC) == 444 (hdr->pixelfmt.flags & DDPF_RGB)) 445 { 446 g_message("Invalid pixel format.\n"); 447 return(0); 448 } 449 */ 450 if((hdr->pixelfmt.flags & DDPF_FOURCC) && 451 memcmp(hdr->pixelfmt.fourcc, "DXT1", 4) && 452 memcmp(hdr->pixelfmt.fourcc, "DXT3", 4) && 453 memcmp(hdr->pixelfmt.fourcc, "DXT5", 4) && 454 memcmp(hdr->pixelfmt.fourcc, "ATI1", 4) && 455 memcmp(hdr->pixelfmt.fourcc, "ATI2", 4)) 456 { 457 g_message("Invalid compression format.\n" 458 "Only DXT1, DXT3, DXT5, ATI1N and ATI2N formats are supported.\n"); 459 return(0); 460 } 461 462 if(hdr->pixelfmt.flags & DDPF_RGB) 463 { 464 if((hdr->pixelfmt.bpp != 8) && 465 (hdr->pixelfmt.bpp != 16) && 466 (hdr->pixelfmt.bpp != 24) && 467 (hdr->pixelfmt.bpp != 32)) 468 { 469 g_message("Invalid BPP.\n"); 470 return(0); 471 } 472 } 473 else if(hdr->pixelfmt.flags & DDPF_LUMINANCE) 474 { 475 if((hdr->pixelfmt.bpp != 8) && 476 (hdr->pixelfmt.bpp != 16)) 477 { 478 g_message("Invalid BPP.\n"); 479 return(0); 480 } 481 482 hdr->pixelfmt.flags |= DDPF_RGB; 483 } 484 else if(hdr->pixelfmt.flags & DDPF_PALETTEINDEXED8) 485 { 486 hdr->pixelfmt.flags |= DDPF_RGB; 487 } 488 489 if(!(hdr->pixelfmt.flags & DDPF_RGB) && 490 !(hdr->pixelfmt.flags & DDPF_ALPHA) && 491 !(hdr->pixelfmt.flags & DDPF_FOURCC) && 492 !(hdr->pixelfmt.flags & DDPF_LUMINANCE)) 493 { 494 g_message("Unknown pixel format! Taking a guess, expect trouble!"); 495 switch(GETL32(hdr->pixelfmt.fourcc)) 496 { 497 case CHAR32('D', 'X', 'T', '1'): 498 case CHAR32('D', 'X', 'T', '3'): 499 case CHAR32('D', 'X', 'T', '5'): 500 case CHAR32('A', 'T', 'I', '1'): 501 case CHAR32('A', 'T', 'I', '2'): 502 hdr->pixelfmt.flags |= DDPF_FOURCC; 503 break; 504 default: 505 switch(hdr->pixelfmt.bpp) 506 { 507 case 8: 508 if(hdr->pixelfmt.flags & DDPF_ALPHAPIXELS) 509 hdr->pixelfmt.flags |= DDPF_ALPHA; 510 else 511 hdr->pixelfmt.flags |= DDPF_LUMINANCE; 512 break; 513 case 16: 514 case 24: 515 case 32: 516 hdr->pixelfmt.flags |= DDPF_RGB; 517 break; 518 default: 519 g_message("Invalid pixel format."); 520 return(0); 521 } 522 break; 523 } 524 } 525 526 return(1); 527 } 528 529 static int load_layer(FILE *fp, dds_header_t *hdr, dds_load_info_t *d, 530 gint32 image, unsigned int level, char *prefix, 531 unsigned int *l, guchar *pixels, unsigned char *buf) 532 { 533 GimpDrawable *drawable; 534 GimpPixelRgn pixel_region; 535 GimpImageType type = GIMP_RGBA_IMAGE; 536 gchar *layer_name; 537 gint x, y, z, n; 538 gint32 layer; 539 unsigned int width = hdr->width >> level; 540 unsigned int height = hdr->height >> level; 541 unsigned int size = hdr->pitch_or_linsize >> (2 * level); 542 int format = DDS_COMPRESS_NONE; 543 544 if(width < 1) width = 1; 545 if(height < 1) height = 1; 546 547 switch(d->bpp) 548 { 549 case 1: 550 if(hdr->pixelfmt.flags & DDPF_PALETTEINDEXED8) 551 type = GIMP_INDEXED_IMAGE; 552 else if(hdr->pixelfmt.rmask == 0xe0) 553 type = GIMP_RGB_IMAGE; 554 else if(hdr->pixelfmt.flags & DDPF_ALPHA) 555 type = GIMP_GRAYA_IMAGE; 556 else 557 type = GIMP_GRAY_IMAGE; 558 break; 559 case 2: 560 if(hdr->pixelfmt.amask == 0xf000) //RGBA4 561 type = GIMP_RGBA_IMAGE; 562 else if(hdr->pixelfmt.amask == 0xff00) //L8A8 563 type = GIMP_GRAYA_IMAGE; 564 else if(hdr->pixelfmt.bmask == 0x1f) //R5G6B5 or RGB5A1 565 type = (hdr->pixelfmt.amask == 0x8000) ? GIMP_RGBA_IMAGE : GIMP_RGB_IMAGE; 566 else //L16 567 type = GIMP_GRAY_IMAGE; 568 break; 569 case 3: type = GIMP_RGB_IMAGE; break; 570 case 4: type = GIMP_RGBA_IMAGE; break; 571 } 572 573 layer_name = (level) ? g_strdup_printf("mipmap %d %s", level, prefix) : 574 g_strdup_printf("main surface %s", prefix); 575 576 layer = gimp_layer_new(image, layer_name, width, height, type, 100, 577 GIMP_NORMAL_MODE); 578 g_free(layer_name); 579 580 gimp_image_add_layer(image, layer, *l); 581 if((*l)++) gimp_drawable_set_visible(layer, FALSE); 582 583 drawable = gimp_drawable_get(layer); 584 585 gimp_pixel_rgn_init(&pixel_region, drawable, 0, 0, drawable->width, 586 drawable->height, TRUE, FALSE); 587 588 if(hdr->pixelfmt.flags & DDPF_FOURCC) 589 { 590 unsigned int w = (width + 3) >> 2; 591 unsigned int h = (height + 3) >> 2; 592 593 switch(GETL32(hdr->pixelfmt.fourcc)) 594 { 595 case CHAR32('D', 'X', 'T', '1'): format = DDS_COMPRESS_BC1; break; 596 case CHAR32('D', 'X', 'T', '3'): format = DDS_COMPRESS_BC2; break; 597 case CHAR32('D', 'X', 'T', '5'): format = DDS_COMPRESS_BC3; break; 598 case CHAR32('A', 'T', 'I', '1'): format = DDS_COMPRESS_BC4; break; 599 case CHAR32('A', 'T', 'I', '2'): format = DDS_COMPRESS_BC5; break; 600 } 601 602 if(w == 0) w = 1; 603 if(h == 0) h = 1; 604 size = w * h; 605 if(format == DDS_COMPRESS_BC1 || format == DDS_COMPRESS_BC4) 606 size *= 8; 607 else 608 size *= 16; 609 } 610 611 if((hdr->flags & DDSD_LINEARSIZE) && 612 !fread(buf, size, 1, fp)) 613 { 614 g_message("Unexpected EOF.\n"); 615 return(0); 616 } 617 618 if(hdr->pixelfmt.flags & DDPF_RGB || hdr->pixelfmt.flags & DDPF_ALPHA) 619 { 620 z = 0; 621 for(y = 0, n = 0; y < height; ++y, ++n) 622 { 623 if(n >= d->tile_height) 624 { 625 gimp_pixel_rgn_set_rect(&pixel_region, pixels, 0, y - n, 626 drawable->width, n); 627 n = 0; 628 if(interactive_dds) 629 gimp_progress_update((double)y / (double)hdr->height); 630 } 631 632 if((hdr->flags & DDSD_PITCH) && 633 !fread(buf, width * d->bpp, 1, fp)) 634 { 635 g_message("Unexpected EOF.\n"); 636 return(0); 637 } 638 639 if(!(hdr->flags & DDSD_LINEARSIZE)) z = 0; 640 641 for(x = 0; x < drawable->width; ++x) 642 { 643 unsigned int pixel = buf[z]; 644 unsigned int pos = (n * drawable->width + x) * d->gimp_bpp; 645 646 if(d->bpp > 1) pixel += ((unsigned int)buf[z + 1] << 8); 647 if(d->bpp > 2) pixel += ((unsigned int)buf[z + 2] << 16); 648 if(d->bpp > 3) pixel += ((unsigned int)buf[z + 3] << 24); 649 650 if(d->bpp >= 3) 651 { 652 if(hdr->pixelfmt.amask == 0xc0000000) // handle RGB10A2 653 { 654 pixels[pos + 0] = (pixel >> d->rshift) >> 2; 655 pixels[pos + 1] = (pixel >> d->gshift) >> 2; 656 pixels[pos + 2] = (pixel >> d->bshift) >> 2; 657 if(hdr->pixelfmt.flags & DDPF_ALPHAPIXELS) 658 pixels[pos + 3] = (pixel >> d->ashift << (8 - d->abits) & d->amask) * 255 / d->amask; 659 } 660 else 661 { 662 pixels[pos] = 663 (pixel >> d->rshift << (8 - d->rbits) & d->rmask) * 255 / d->rmask; 664 pixels[pos + 1] = 665 (pixel >> d->gshift << (8 - d->gbits) & d->gmask) * 255 / d->gmask; 666 pixels[pos + 2] = 667 (pixel >> d->bshift << (8 - d->bbits) & d->bmask) * 255 / d->bmask; 668 if(hdr->pixelfmt.flags & DDPF_ALPHAPIXELS) 669 { 670 pixels[pos + 3] = 671 (pixel >> d->ashift << (8 - d->abits) & d->amask) * 255 / d->amask; 672 } 673 } 674 } 675 else if(d->bpp == 2) 676 { 677 if(hdr->pixelfmt.amask == 0xf000) //RGBA4 678 { 679 pixels[pos] = 680 (pixel >> d->rshift << (8 - d->rbits) & d->rmask) * 255 / d->rmask; 681 pixels[pos + 1] = 682 (pixel >> d->gshift << (8 - d->gbits) & d->gmask) * 255 / d->gmask; 683 pixels[pos + 2] = 684 (pixel >> d->bshift << (8 - d->bbits) & d->bmask) * 255 / d->bmask; 685 pixels[pos + 3] = 686 (pixel >> d->ashift << (8 - d->abits) & d->amask) * 255 / d->amask; 687 } 688 else if(hdr->pixelfmt.amask == 0xff00) //L8A8 689 { 690 pixels[pos] = 691 (pixel >> d->rshift << (8 - d->rbits) & d->rmask) * 255 / d->rmask; 692 pixels[pos + 1] = 693 (pixel >> d->ashift << (8 - d->abits) & d->amask) * 255 / d->amask; 694 } 695 else if(hdr->pixelfmt.bmask == 0x1f) //R5G6B5 or RGB5A1 696 { 697 pixels[pos] = 698 (pixel >> d->rshift << (8 - d->rbits) & d->rmask) * 255 / d->rmask; 699 pixels[pos + 1] = 700 (pixel >> d->gshift << (8 - d->gbits) & d->gmask) * 255 / d->gmask; 701 pixels[pos + 2] = 702 (pixel >> d->bshift << (8 - d->bbits) & d->bmask) * 255 / d->bmask; 703 if(hdr->pixelfmt.amask == 0x8000) 704 { 705 pixels[pos + 3] = 706 (pixel >> d->ashift << (8 - d->abits) & d->amask) * 255 / d->amask; 707 } 708 } 709 else //L16 710 pixels[pos] = (unsigned char)(255 * ((float)(pixel & 0xffff) / 65535.0f)); 711 } 712 else 713 { 714 if(hdr->pixelfmt.flags & DDPF_PALETTEINDEXED8) 715 { 716 pixels[pos] = pixel & 0xff; 717 } 718 else if(hdr->pixelfmt.rmask == 0xe0) // R3G3B2 719 { 720 pixels[pos] = 721 (pixel >> d->rshift << (8 - d->rbits) & d->rmask) * 255 / d->rmask; 722 pixels[pos + 1] = 723 (pixel >> d->gshift << (8 - d->gbits) & d->gmask) * 255 / d->gmask; 724 pixels[pos + 2] = 725 (pixel >> d->bshift << (8 - d->bbits) & d->bmask) * 255 / d->bmask; 726 } 727 else if(hdr->pixelfmt.flags & DDPF_ALPHA) 728 { 729 pixels[pos + 0] = 255; 730 pixels[pos + 1] = pixel & 0xff; 731 } 732 else // LUMINANCE 733 { 734 pixels[pos] = pixel & 0xff; 735 } 736 } 737 738 z += d->bpp; 739 } 740 } 741 742 gimp_pixel_rgn_set_rect(&pixel_region, pixels, 0, y - n, 743 drawable->width, n); 744 } 745 else if(hdr->pixelfmt.flags & DDPF_FOURCC) 746 { 747 unsigned char *dst; 748 749 if(!(hdr->flags & DDSD_LINEARSIZE)) 750 { 751 g_message("Image marked as compressed, but DDSD_LINEARSIZE is not set.\n"); 752 return(0); 753 } 754 755 dst = g_malloc(width * height * d->gimp_bpp); 756 memset(dst, 0, width * height * d->gimp_bpp); 757 758 if(d->gimp_bpp == 4) 759 { 760 for(y = 0; y < height; ++y) 761 for(x = 0; x < width; ++x) 762 dst[y * (width * 4) + x + 3] = 255; 763 } 764 765 dxt_decompress(dst, buf, format, size, width, height, d->gimp_bpp); 766 767 z = 0; 768 for(y = 0, n = 0; y < height; ++y, ++n) 769 { 770 if(n >= d->tile_height) 771 { 772 gimp_pixel_rgn_set_rect(&pixel_region, pixels, 0, y - n, 773 drawable->width, n); 774 n = 0; 775 if(interactive_dds) 776 gimp_progress_update((double)y / (double)hdr->height); 777 } 778 779 memcpy(pixels + n * drawable->width * d->gimp_bpp, 780 dst + y * drawable->width * d->gimp_bpp, 781 width * d->gimp_bpp); 782 } 783 784 gimp_pixel_rgn_set_rect(&pixel_region, pixels, 0, y - n, 785 drawable->width, n); 786 787 g_free(dst); 788 } 789 790 gimp_drawable_flush(drawable); 791 gimp_drawable_detach(drawable); 792 793 return(1); 794 } 795 796 static int load_mipmaps(FILE *fp, dds_header_t *hdr, dds_load_info_t *d, 797 gint32 image, char *prefix, unsigned int *l, 798 guchar *pixels, unsigned char *buf) 799 { 800 unsigned int level; 801 802 if((hdr->flags & DDSD_MIPMAPCOUNT) && 803 (hdr->caps.caps1 & DDSCAPS_MIPMAP)) 804 { 805 for(level = 1; level < hdr->num_mipmaps; ++level) 806 { 807 if(!load_layer(fp, hdr, d, image, level, prefix, l, pixels, buf)) 808 return(0); 809 } 810 } 811 return(1); 812 } 813 814 static int load_face(FILE *fp, dds_header_t *hdr, dds_load_info_t *d, 815 gint32 image, char *prefix, unsigned int *l, 816 guchar *pixels, unsigned char *buf) 817 { 818 if(!load_layer(fp, hdr, d, image, 0, prefix, l, pixels, buf)) 819 return(0); 820 return(load_mipmaps(fp, hdr, d, image, prefix, l, pixels, buf)); 821 } 822 823 static unsigned char color_bits(unsigned int mask) 824 { 825 unsigned char i = 0; 826 827 while(mask) 828 { 829 if(mask & 1) ++i; 830 mask >>= 1; 831 } 832 return(i); 833 } 834 835 static unsigned char color_shift(unsigned int mask) 836 { 837 unsigned char i = 0; 838 839 if(!mask) return(0); 840 while(!((mask >> i) & 1)) ++i; 841 return(i); 842 } 843 844 static void load_dialog_response(GtkWidget *widget, gint response_id, 845 gpointer data) 846 { 847 switch(response_id) 848 { 849 case GTK_RESPONSE_OK: 850 runme = 1; 851 default: 852 gtk_widget_destroy(widget); 853 break; 854 } 855 } 856 857 static void toggle_clicked(GtkWidget *widget, gpointer data) 858 { 859 int *flag = (int*)data; 860 (*flag) = !(*flag); 861 } 862 863 static int load_dialog(void) 864 { 865 GtkWidget *dlg; 866 GtkWidget *vbox; 867 GtkWidget *check; 868 869 dlg = gimp_dialog_new("Load DDS", "dds", NULL, GTK_WIN_POS_MOUSE, 870 gimp_standard_help_func, LOAD_PROC, 871 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, 872 GTK_STOCK_OK, GTK_RESPONSE_OK, 873 NULL); 874 875 gtk_signal_connect(GTK_OBJECT(dlg), "response", 876 GTK_SIGNAL_FUNC(load_dialog_response), 877 0); 878 gtk_signal_connect(GTK_OBJECT(dlg), "destroy", 879 GTK_SIGNAL_FUNC(gtk_main_quit), 880 0); 881 882 vbox = gtk_vbox_new(0, 8); 883 gtk_container_set_border_width(GTK_CONTAINER(vbox), 8); 884 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dlg)->vbox), vbox, 1, 1, 0); 885 gtk_widget_show(vbox); 886 887 check = gtk_check_button_new_with_label("Load mipmaps"); 888 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), dds_read_vals.mipmaps); 889 gtk_signal_connect(GTK_OBJECT(check), "clicked", 890 GTK_SIGNAL_FUNC(toggle_clicked), &dds_read_vals.mipmaps); 891 gtk_box_pack_start(GTK_BOX(vbox), check, 1, 1, 0); 892 gtk_widget_show(check); 893 894 check = gtk_check_button_new_with_label("Show this dialog"); 895 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), dds_read_vals.show_dialog); 896 gtk_signal_connect(GTK_OBJECT(check), "clicked", 897 GTK_SIGNAL_FUNC(toggle_clicked), &dds_read_vals.show_dialog); 898 gtk_box_pack_start(GTK_BOX(vbox), check, 1, 1, 0); 899 gtk_widget_show(check); 900 901 gtk_widget_show(dlg); 902 903 runme = 0; 904 905 gtk_main(); 906 907 return(runme); 908 }
| ViewVC Help | |
| Powered by ViewVC 1.0.4 |