Parent Directory
|
Revision Log
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 |