Parent Directory
|
Revision Log
Added routines to decode YCoCg and alpha exponent encoded images. They can be found in the Filters/Colors menu.
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 FOURCC('A', 'T', 'I', '1'): 146 d.bpp = d.gimp_bpp = 1; 147 type = GIMP_GRAY; 148 break; 149 case FOURCC('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 FOURCC('D', 'X', 'T', '1'): 498 case FOURCC('D', 'X', 'T', '3'): 499 case FOURCC('D', 'X', 'T', '5'): 500 case FOURCC('A', 'T', 'I', '1'): 501 case FOURCC('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(hdr->pixelfmt.flags & DDPF_FOURCC) 545 { 546 width = MAX(width, 4); 547 height = MAX(height, 4); 548 } 549 else 550 { 551 if(width < 1) width = 1; 552 if(height < 1) height = 1; 553 } 554 555 switch(d->bpp) 556 { 557 case 1: 558 if(hdr->pixelfmt.flags & DDPF_PALETTEINDEXED8) 559 type = GIMP_INDEXED_IMAGE; 560 else if(hdr->pixelfmt.rmask == 0xe0) 561 type = GIMP_RGB_IMAGE; 562 else if(hdr->pixelfmt.flags & DDPF_ALPHA) 563 type = GIMP_GRAYA_IMAGE; 564 else 565 type = GIMP_GRAY_IMAGE; 566 break; 567 case 2: 568 if(hdr->pixelfmt.amask == 0xf000) //RGBA4 569 type = GIMP_RGBA_IMAGE; 570 else if(hdr->pixelfmt.amask == 0xff00) //L8A8 571 type = GIMP_GRAYA_IMAGE; 572 else if(hdr->pixelfmt.bmask == 0x1f) //R5G6B5 or RGB5A1 573 type = (hdr->pixelfmt.amask == 0x8000) ? GIMP_RGBA_IMAGE : GIMP_RGB_IMAGE; 574 else //L16 575 type = GIMP_GRAY_IMAGE; 576 break; 577 case 3: type = GIMP_RGB_IMAGE; break; 578 case 4: type = GIMP_RGBA_IMAGE; break; 579 } 580 581 layer_name = (level) ? g_strdup_printf("mipmap %d %s", level, prefix) : 582 g_strdup_printf("main surface %s", prefix); 583 584 layer = gimp_layer_new(image, layer_name, width, height, type, 100, 585 GIMP_NORMAL_MODE); 586 g_free(layer_name); 587 588 gimp_image_add_layer(image, layer, *l); 589 if((*l)++) gimp_drawable_set_visible(layer, FALSE); 590 591 drawable = gimp_drawable_get(layer); 592 593 gimp_pixel_rgn_init(&pixel_region, drawable, 0, 0, drawable->width, 594 drawable->height, TRUE, FALSE); 595 596 if(hdr->pixelfmt.flags & DDPF_FOURCC) 597 { 598 unsigned int w = (width + 3) >> 2; 599 unsigned int h = (height + 3) >> 2; 600 601 switch(GETL32(hdr->pixelfmt.fourcc)) 602 { 603 case FOURCC('D', 'X', 'T', '1'): format = DDS_COMPRESS_BC1; break; 604 case FOURCC('D', 'X', 'T', '3'): format = DDS_COMPRESS_BC2; break; 605 case FOURCC('D', 'X', 'T', '5'): format = DDS_COMPRESS_BC3; break; 606 case FOURCC('A', 'T', 'I', '1'): format = DDS_COMPRESS_BC4; break; 607 case FOURCC('A', 'T', 'I', '2'): format = DDS_COMPRESS_BC5; break; 608 } 609 610 size = w * h; 611 if(format == DDS_COMPRESS_BC1 || format == DDS_COMPRESS_BC4) 612 size *= 8; 613 else 614 size *= 16; 615 } 616 617 if((hdr->flags & DDSD_LINEARSIZE) && 618 !fread(buf, size, 1, fp)) 619 { 620 g_message("Unexpected EOF.\n"); 621 return(0); 622 } 623 624 if(hdr->pixelfmt.flags & DDPF_RGB || hdr->pixelfmt.flags & DDPF_ALPHA) 625 { 626 z = 0; 627 for(y = 0, n = 0; y < height; ++y, ++n) 628 { 629 if(n >= d->tile_height) 630 { 631 gimp_pixel_rgn_set_rect(&pixel_region, pixels, 0, y - n, 632 drawable->width, n); 633 n = 0; 634 if(interactive_dds) 635 gimp_progress_update((double)y / (double)hdr->height); 636 } 637 638 if((hdr->flags & DDSD_PITCH) && 639 !fread(buf, width * d->bpp, 1, fp)) 640 { 641 g_message("Unexpected EOF.\n"); 642 return(0); 643 } 644 645 if(!(hdr->flags & DDSD_LINEARSIZE)) z = 0; 646 647 for(x = 0; x < drawable->width; ++x) 648 { 649 unsigned int pixel = buf[z]; 650 unsigned int pos = (n * drawable->width + x) * d->gimp_bpp; 651 652 if(d->bpp > 1) pixel += ((unsigned int)buf[z + 1] << 8); 653 if(d->bpp > 2) pixel += ((unsigned int)buf[z + 2] << 16); 654 if(d->bpp > 3) pixel += ((unsigned int)buf[z + 3] << 24); 655 656 if(d->bpp >= 3) 657 { 658 if(hdr->pixelfmt.amask == 0xc0000000) // handle RGB10A2 659 { 660 pixels[pos + 0] = (pixel >> d->rshift) >> 2; 661 pixels[pos + 1] = (pixel >> d->gshift) >> 2; 662 pixels[pos + 2] = (pixel >> d->bshift) >> 2; 663 if(hdr->pixelfmt.flags & DDPF_ALPHAPIXELS) 664 pixels[pos + 3] = (pixel >> d->ashift << (8 - d->abits) & d->amask) * 255 / d->amask; 665 } 666 else 667 { 668 pixels[pos] = 669 (pixel >> d->rshift << (8 - d->rbits) & d->rmask) * 255 / d->rmask; 670 pixels[pos + 1] = 671 (pixel >> d->gshift << (8 - d->gbits) & d->gmask) * 255 / d->gmask; 672 pixels[pos + 2] = 673 (pixel >> d->bshift << (8 - d->bbits) & d->bmask) * 255 / d->bmask; 674 if(hdr->pixelfmt.flags & DDPF_ALPHAPIXELS) 675 { 676 pixels[pos + 3] = 677 (pixel >> d->ashift << (8 - d->abits) & d->amask) * 255 / d->amask; 678 } 679 } 680 } 681 else if(d->bpp == 2) 682 { 683 if(hdr->pixelfmt.amask == 0xf000) //RGBA4 684 { 685 pixels[pos] = 686 (pixel >> d->rshift << (8 - d->rbits) & d->rmask) * 255 / d->rmask; 687 pixels[pos + 1] = 688 (pixel >> d->gshift << (8 - d->gbits) & d->gmask) * 255 / d->gmask; 689 pixels[pos + 2] = 690 (pixel >> d->bshift << (8 - d->bbits) & d->bmask) * 255 / d->bmask; 691 pixels[pos + 3] = 692 (pixel >> d->ashift << (8 - d->abits) & d->amask) * 255 / d->amask; 693 } 694 else if(hdr->pixelfmt.amask == 0xff00) //L8A8 695 { 696 pixels[pos] = 697 (pixel >> d->rshift << (8 - d->rbits) & d->rmask) * 255 / d->rmask; 698 pixels[pos + 1] = 699 (pixel >> d->ashift << (8 - d->abits) & d->amask) * 255 / d->amask; 700 } 701 else if(hdr->pixelfmt.bmask == 0x1f) //R5G6B5 or RGB5A1 702 { 703 pixels[pos] = 704 (pixel >> d->rshift << (8 - d->rbits) & d->rmask) * 255 / d->rmask; 705 pixels[pos + 1] = 706 (pixel >> d->gshift << (8 - d->gbits) & d->gmask) * 255 / d->gmask; 707 pixels[pos + 2] = 708 (pixel >> d->bshift << (8 - d->bbits) & d->bmask) * 255 / d->bmask; 709 if(hdr->pixelfmt.amask == 0x8000) 710 { 711 pixels[pos + 3] = 712 (pixel >> d->ashift << (8 - d->abits) & d->amask) * 255 / d->amask; 713 } 714 } 715 else //L16 716 pixels[pos] = (unsigned char)(255 * ((float)(pixel & 0xffff) / 65535.0f)); 717 } 718 else 719 { 720 if(hdr->pixelfmt.flags & DDPF_PALETTEINDEXED8) 721 { 722 pixels[pos] = pixel & 0xff; 723 } 724 else if(hdr->pixelfmt.rmask == 0xe0) // R3G3B2 725 { 726 pixels[pos] = 727 (pixel >> d->rshift << (8 - d->rbits) & d->rmask) * 255 / d->rmask; 728 pixels[pos + 1] = 729 (pixel >> d->gshift << (8 - d->gbits) & d->gmask) * 255 / d->gmask; 730 pixels[pos + 2] = 731 (pixel >> d->bshift << (8 - d->bbits) & d->bmask) * 255 / d->bmask; 732 } 733 else if(hdr->pixelfmt.flags & DDPF_ALPHA) 734 { 735 pixels[pos + 0] = 255; 736 pixels[pos + 1] = pixel & 0xff; 737 } 738 else // LUMINANCE 739 { 740 pixels[pos] = pixel & 0xff; 741 } 742 } 743 744 z += d->bpp; 745 } 746 } 747 748 gimp_pixel_rgn_set_rect(&pixel_region, pixels, 0, y - n, 749 drawable->width, n); 750 } 751 else if(hdr->pixelfmt.flags & DDPF_FOURCC) 752 { 753 unsigned char *dst; 754 755 if(!(hdr->flags & DDSD_LINEARSIZE)) 756 { 757 g_message("Image marked as compressed, but DDSD_LINEARSIZE is not set.\n"); 758 return(0); 759 } 760 761 dst = g_malloc(width * height * d->gimp_bpp); 762 memset(dst, 0, width * height * d->gimp_bpp); 763 764 if(d->gimp_bpp == 4) 765 { 766 for(y = 0; y < height; ++y) 767 for(x = 0; x < width; ++x) 768 dst[y * (width * 4) + x + 3] = 255; 769 } 770 771 dxt_decompress(dst, buf, format, size, width, height, d->gimp_bpp); 772 773 z = 0; 774 for(y = 0, n = 0; y < height; ++y, ++n) 775 { 776 if(n >= d->tile_height) 777 { 778 gimp_pixel_rgn_set_rect(&pixel_region, pixels, 0, y - n, 779 drawable->width, n); 780 n = 0; 781 if(interactive_dds) 782 gimp_progress_update((double)y / (double)hdr->height); 783 } 784 785 memcpy(pixels + n * drawable->width * d->gimp_bpp, 786 dst + y * drawable->width * d->gimp_bpp, 787 width * d->gimp_bpp); 788 } 789 790 gimp_pixel_rgn_set_rect(&pixel_region, pixels, 0, y - n, 791 drawable->width, n); 792 793 g_free(dst); 794 } 795 796 gimp_drawable_flush(drawable); 797 gimp_drawable_detach(drawable); 798 799 return(1); 800 } 801 802 static int load_mipmaps(FILE *fp, dds_header_t *hdr, dds_load_info_t *d, 803 gint32 image, char *prefix, unsigned int *l, 804 guchar *pixels, unsigned char *buf) 805 { 806 unsigned int level; 807 808 if((hdr->flags & DDSD_MIPMAPCOUNT) && 809 (hdr->caps.caps1 & DDSCAPS_MIPMAP)) 810 { 811 for(level = 1; level < hdr->num_mipmaps; ++level) 812 { 813 if(!load_layer(fp, hdr, d, image, level, prefix, l, pixels, buf)) 814 return(0); 815 } 816 } 817 return(1); 818 } 819 820 static int load_face(FILE *fp, dds_header_t *hdr, dds_load_info_t *d, 821 gint32 image, char *prefix, unsigned int *l, 822 guchar *pixels, unsigned char *buf) 823 { 824 if(!load_layer(fp, hdr, d, image, 0, prefix, l, pixels, buf)) 825 return(0); 826 return(load_mipmaps(fp, hdr, d, image, prefix, l, pixels, buf)); 827 } 828 829 static unsigned char color_bits(unsigned int mask) 830 { 831 unsigned char i = 0; 832 833 while(mask) 834 { 835 if(mask & 1) ++i; 836 mask >>= 1; 837 } 838 return(i); 839 } 840 841 static unsigned char color_shift(unsigned int mask) 842 { 843 unsigned char i = 0; 844 845 if(!mask) return(0); 846 while(!((mask >> i) & 1)) ++i; 847 return(i); 848 } 849 850 static void load_dialog_response(GtkWidget *widget, gint response_id, 851 gpointer data) 852 { 853 switch(response_id) 854 { 855 case GTK_RESPONSE_OK: 856 runme = 1; 857 default: 858 gtk_widget_destroy(widget); 859 break; 860 } 861 } 862 863 static void toggle_clicked(GtkWidget *widget, gpointer data) 864 { 865 int *flag = (int*)data; 866 (*flag) = !(*flag); 867 } 868 869 static int load_dialog(void) 870 { 871 GtkWidget *dlg; 872 GtkWidget *vbox; 873 GtkWidget *check; 874 875 dlg = gimp_dialog_new("Load DDS", "dds", NULL, GTK_WIN_POS_MOUSE, 876 gimp_standard_help_func, LOAD_PROC, 877 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, 878 GTK_STOCK_OK, GTK_RESPONSE_OK, 879 NULL); 880 881 gtk_signal_connect(GTK_OBJECT(dlg), "response", 882 GTK_SIGNAL_FUNC(load_dialog_response), 883 0); 884 gtk_signal_connect(GTK_OBJECT(dlg), "destroy", 885 GTK_SIGNAL_FUNC(gtk_main_quit), 886 0); 887 888 vbox = gtk_vbox_new(0, 8); 889 gtk_container_set_border_width(GTK_CONTAINER(vbox), 8); 890 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dlg)->vbox), vbox, 1, 1, 0); 891 gtk_widget_show(vbox); 892 893 check = gtk_check_button_new_with_label("Load mipmaps"); 894 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), dds_read_vals.mipmaps); 895 gtk_signal_connect(GTK_OBJECT(check), "clicked", 896 GTK_SIGNAL_FUNC(toggle_clicked), &dds_read_vals.mipmaps); 897 gtk_box_pack_start(GTK_BOX(vbox), check, 1, 1, 0); 898 gtk_widget_show(check); 899 900 check = gtk_check_button_new_with_label("Show this dialog"); 901 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), dds_read_vals.show_dialog); 902 gtk_signal_connect(GTK_OBJECT(check), "clicked", 903 GTK_SIGNAL_FUNC(toggle_clicked), &dds_read_vals.show_dialog); 904 gtk_box_pack_start(GTK_BOX(vbox), check, 1, 1, 0); 905 gtk_widget_show(check); 906 907 gtk_widget_show(dlg); 908 909 runme = 0; 910 911 gtk_main(); 912 913 return(runme); 914 }
| ViewVC Help | |
| Powered by ViewVC 1.0.4 |