diff --git a/plug-ins/file-dds/dds.c b/plug-ins/file-dds/dds.c index e5f174e0fb..d032d22f02 100644 --- a/plug-ins/file-dds/dds.c +++ b/plug-ins/file-dds/dds.c @@ -176,6 +176,14 @@ dds_create_procedure (GimpPlugIn *plug_in, FALSE, G_PARAM_READWRITE); + GIMP_PROC_ARG_BOOLEAN (procedure, "bc1-use-transparency", + _("Always use _transparency for BC1/DXT1"), + _("Interprets transparency for BC1/DXT1 images even when " + "DDPF_ALPHAPIXELS is not set; if disabled, sets it " + "to opaque black"), + TRUE, + G_PARAM_READWRITE); + GIMP_PROC_ARG_BOOLEAN (procedure, "decode-images", _("Automatically decode YCoCg/AE_xp images when detected"), _("Decode YCoCg/AExp images when detected"), diff --git a/plug-ins/file-dds/dds.h b/plug-ins/file-dds/dds.h index d5d9bcdea2..8fa4453d8f 100644 --- a/plug-ins/file-dds/dds.h +++ b/plug-ins/file-dds/dds.h @@ -51,6 +51,7 @@ typedef enum DDS_COMPRESS_AEXP, /* DXT5 */ DDS_COMPRESS_YCOCG, /* DXT5 */ DDS_COMPRESS_YCOCGS, /* DXT5 */ + _DDS_COMPRESS_BC1_NO_ALPHA, /* For internal use only. */ DDS_COMPRESS_MAX } DDS_COMPRESSION_TYPE; diff --git a/plug-ins/file-dds/ddsread.c b/plug-ins/file-dds/ddsread.c index 7a56279816..3aec710e62 100644 --- a/plug-ins/file-dds/ddsread.c +++ b/plug-ins/file-dds/ddsread.c @@ -139,6 +139,7 @@ read_dds (GFile *file, gint i, j; guint computed_pitch_or_linsize; gboolean flip_import; + gboolean bc1_use_transparency; if (interactive) { @@ -149,9 +150,10 @@ read_dds (GFile *file, } g_object_get (config, - "load-mipmaps", &read_mipmaps, - "flip-image", &flip_import, - "decode-images", &decode_images, + "load-mipmaps", &read_mipmaps, + "flip-image", &flip_import, + "bc1-use-transparency", &bc1_use_transparency, + "decode-images", &decode_images, NULL); fp = g_fopen (g_file_peek_path (file), "rb"); @@ -307,7 +309,8 @@ read_dds (GFile *file, if (hdr.pixelfmt.flags & DDPF_FOURCC) { /* fourcc is dXt* or rXgb */ - if (hdr.pixelfmt.fourcc[1] == 'X') + if (hdr.pixelfmt.fourcc[1] == 'X' && + (hdr.pixelfmt.fourcc[3] != '1' || bc1_use_transparency)) hdr.pixelfmt.flags |= DDPF_ALPHAPIXELS; } @@ -1841,6 +1844,12 @@ load_layer (FILE *fp, dst[y * (width * 4) + (x * 4) + 3] = 255; } + if (format == DDS_COMPRESS_BC1 && + ! (hdr->pixelfmt.flags & DDPF_ALPHAPIXELS)) + { + format = _DDS_COMPRESS_BC1_NO_ALPHA; + } + dxt_decompress (dst, buf, format, size, width, height, d->gimp_bpp, hdr->pixelfmt.flags & DDPF_NORMAL); @@ -2013,6 +2022,7 @@ load_dialog (GimpProcedure *procedure, "dds-read-box", "load-mipmaps", "flip-image", + "bc1-use-transparency", "decode-images", NULL); gtk_box_set_spacing (GTK_BOX (vbox), 8); diff --git a/plug-ins/file-dds/dxt.c b/plug-ins/file-dds/dxt.c index 28d407a00f..e0c214336d 100644 --- a/plug-ins/file-dds/dxt.c +++ b/plug-ins/file-dds/dxt.c @@ -1329,7 +1329,18 @@ decode_color_block (unsigned char *block, d[1] = colors[idx][1]; d[2] = colors[idx][0]; if (format == DDS_COMPRESS_BC1) - d[3] = ((c0 <= c1) && idx == 3) ? 0 : 255; + { + d[3] = ((c0 <= c1) && idx == 3) ? 0 : 255; + } + else if (format == _DDS_COMPRESS_BC1_NO_ALPHA) + { + /* BC1, but interpret transparent as black */ + if ((c0 <= c1) && idx == 3) + { + d[0] = d[1] = d[2] = 0; + } + d[3] = 255; + } indices >>= 2; d += 4; } @@ -1486,7 +1497,7 @@ dxt_decompress (unsigned char *dst, { memset(block, 0, 16 * 4); - if (format == DDS_COMPRESS_BC1) + if (format == DDS_COMPRESS_BC1 || format == _DDS_COMPRESS_BC1_NO_ALPHA) { decode_color_block(block, s, format); s += 8;