Commit d25348ca authored by Massimo Valentini's avatar Massimo Valentini Committed by Jehan

file-dds: support for DXT2/DXT4, initial build and GEGL-related fixes

parent 79bc2dc1
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
*/ */
#include <math.h> #include <math.h>
#include "color.h"
int linear_to_sRGB(int c) int linear_to_sRGB(int c)
{ {
......
...@@ -440,6 +440,7 @@ GimpPDBStatusType read_dds(gchar *filename, gint32 *imageID) ...@@ -440,6 +440,7 @@ GimpPDBStatusType read_dds(gchar *filename, gint32 *imageID)
} }
gimp_image_set_active_layer(image, layers[0]); gimp_image_set_active_layer(image, layers[0]);
g_free (layers);
*imageID = image; *imageID = image;
...@@ -541,7 +542,9 @@ static int validate_header(dds_header_t *hdr) ...@@ -541,7 +542,9 @@ static int validate_header(dds_header_t *hdr)
if((hdr->pixelfmt.flags & DDPF_FOURCC) && if((hdr->pixelfmt.flags & DDPF_FOURCC) &&
fourcc != FOURCC('D','X','T','1') && fourcc != FOURCC('D','X','T','1') &&
fourcc != FOURCC('D','X','T','2') &&
fourcc != FOURCC('D','X','T','3') && fourcc != FOURCC('D','X','T','3') &&
fourcc != FOURCC('D','X','T','4') &&
fourcc != FOURCC('D','X','T','5') && fourcc != FOURCC('D','X','T','5') &&
fourcc != FOURCC('R','X','G','B') && fourcc != FOURCC('R','X','G','B') &&
fourcc != FOURCC('A','T','I','1') && fourcc != FOURCC('A','T','I','1') &&
...@@ -597,7 +600,9 @@ static int validate_header(dds_header_t *hdr) ...@@ -597,7 +600,9 @@ static int validate_header(dds_header_t *hdr)
switch(fourcc) switch(fourcc)
{ {
case FOURCC('D','X','T','1'): case FOURCC('D','X','T','1'):
case FOURCC('D','X','T','2'):
case FOURCC('D','X','T','3'): case FOURCC('D','X','T','3'):
case FOURCC('D','X','T','4'):
case FOURCC('D','X','T','5'): case FOURCC('D','X','T','5'):
case FOURCC('R','X','G','B'): case FOURCC('R','X','G','B'):
case FOURCC('A','T','I','1'): case FOURCC('A','T','I','1'):
...@@ -796,6 +801,17 @@ static int setup_dxgi_format(dds_header_t *hdr, dds_header_dx10_t *dx10hdr) ...@@ -796,6 +801,17 @@ static int setup_dxgi_format(dds_header_t *hdr, dds_header_dx10_t *dx10hdr)
return(1); return(1);
} }
static const Babl*
premultiplied_variant (const Babl* format)
{
if (format == babl_format ("R'G'B'A u8"))
return babl_format ("R'aG'aB'aA u8");
else
g_printerr ("Add format %s to premultiplied_variant() %s: %d\n", babl_get_name (format), __FILE__, __LINE__);
return format;
}
static int load_layer(FILE *fp, dds_header_t *hdr, dds_load_info_t *d, static int load_layer(FILE *fp, dds_header_t *hdr, dds_load_info_t *d,
gint32 image, unsigned int level, char *prefix, gint32 image, unsigned int level, char *prefix,
unsigned int *l, guchar *pixels, unsigned char *buf) unsigned int *l, guchar *pixels, unsigned char *buf)
...@@ -888,7 +904,9 @@ static int load_layer(FILE *fp, dds_header_t *hdr, dds_load_info_t *d, ...@@ -888,7 +904,9 @@ static int load_layer(FILE *fp, dds_header_t *hdr, dds_load_info_t *d,
switch(GETL32(hdr->pixelfmt.fourcc)) switch(GETL32(hdr->pixelfmt.fourcc))
{ {
case FOURCC('D','X','T','1'): format = DDS_COMPRESS_BC1; break; case FOURCC('D','X','T','1'): format = DDS_COMPRESS_BC1; break;
case FOURCC('D','X','T','2'): bablfmt = premultiplied_variant (bablfmt);
case FOURCC('D','X','T','3'): format = DDS_COMPRESS_BC2; break; case FOURCC('D','X','T','3'): format = DDS_COMPRESS_BC2; break;
case FOURCC('D','X','T','4'): bablfmt = premultiplied_variant (bablfmt);
case FOURCC('D','X','T','5'): format = DDS_COMPRESS_BC3; break; case FOURCC('D','X','T','5'): format = DDS_COMPRESS_BC3; break;
case FOURCC('R','X','G','B'): format = DDS_COMPRESS_BC3; break; case FOURCC('R','X','G','B'): format = DDS_COMPRESS_BC3; break;
case FOURCC('A','T','I','1'): case FOURCC('A','T','I','1'):
...@@ -920,7 +938,7 @@ static int load_layer(FILE *fp, dds_header_t *hdr, dds_load_info_t *d, ...@@ -920,7 +938,7 @@ static int load_layer(FILE *fp, dds_header_t *hdr, dds_load_info_t *d,
{ {
if(n >= d->tile_height) if(n >= d->tile_height)
{ {
gegl_buffer_set(buffer, GEGL_RECTANGLE(0, y - n, layerw, n), 1.0, gegl_buffer_set(buffer, GEGL_RECTANGLE(0, y - n, layerw, n), 0,
bablfmt, pixels, GEGL_AUTO_ROWSTRIDE); bablfmt, pixels, GEGL_AUTO_ROWSTRIDE);
n = 0; n = 0;
gimp_progress_update((double)y / (double)hdr->height); gimp_progress_update((double)y / (double)hdr->height);
...@@ -1036,7 +1054,7 @@ static int load_layer(FILE *fp, dds_header_t *hdr, dds_load_info_t *d, ...@@ -1036,7 +1054,7 @@ static int load_layer(FILE *fp, dds_header_t *hdr, dds_load_info_t *d,
} }
} }
gegl_buffer_set(buffer, GEGL_RECTANGLE(0, y - n, layerw, n), 1.0, gegl_buffer_set(buffer, GEGL_RECTANGLE(0, y - n, layerw, n), 0,
bablfmt, pixels, GEGL_AUTO_ROWSTRIDE); bablfmt, pixels, GEGL_AUTO_ROWSTRIDE);
} }
else if(hdr->pixelfmt.flags & DDPF_FOURCC) else if(hdr->pixelfmt.flags & DDPF_FOURCC)
...@@ -1067,7 +1085,7 @@ static int load_layer(FILE *fp, dds_header_t *hdr, dds_load_info_t *d, ...@@ -1067,7 +1085,7 @@ static int load_layer(FILE *fp, dds_header_t *hdr, dds_load_info_t *d,
{ {
if(n >= d->tile_height) if(n >= d->tile_height)
{ {
gegl_buffer_set(buffer, GEGL_RECTANGLE(0, y - n, layerw, n), 1.0, gegl_buffer_set(buffer, GEGL_RECTANGLE(0, y - n, layerw, n), 0,
bablfmt, pixels, GEGL_AUTO_ROWSTRIDE); bablfmt, pixels, GEGL_AUTO_ROWSTRIDE);
n = 0; n = 0;
gimp_progress_update((double)y / (double)hdr->height); gimp_progress_update((double)y / (double)hdr->height);
...@@ -1078,7 +1096,7 @@ static int load_layer(FILE *fp, dds_header_t *hdr, dds_load_info_t *d, ...@@ -1078,7 +1096,7 @@ static int load_layer(FILE *fp, dds_header_t *hdr, dds_load_info_t *d,
width * d->gimp_bpp); width * d->gimp_bpp);
} }
gegl_buffer_set(buffer, GEGL_RECTANGLE(0, y - n, layerw, n), 1.0, gegl_buffer_set(buffer, GEGL_RECTANGLE(0, y - n, layerw, n), 0,
bablfmt, pixels, GEGL_AUTO_ROWSTRIDE); bablfmt, pixels, GEGL_AUTO_ROWSTRIDE);
g_free(dst); g_free(dst);
......
...@@ -765,7 +765,7 @@ static struct ...@@ -765,7 +765,7 @@ static struct
* if (texel_alpha < alpha_test_threshold) * if (texel_alpha < alpha_test_threshold)
* discard; * discard;
*/ */
float calc_alpha_test_coverage(unsigned char *src, static float calc_alpha_test_coverage(unsigned char *src,
unsigned int width, unsigned int height, int bpp, unsigned int width, unsigned int height, int bpp,
float alpha_test_threshold, float alpha_test_threshold,
float alpha_scale) float alpha_scale)
...@@ -796,7 +796,7 @@ float calc_alpha_test_coverage(unsigned char *src, ...@@ -796,7 +796,7 @@ float calc_alpha_test_coverage(unsigned char *src,
return (float)coverage / (width * height); return (float)coverage / (width * height);
} }
void scale_alpha_to_coverage(unsigned char *img, static void scale_alpha_to_coverage(unsigned char *img,
unsigned int width, unsigned int height, int bpp, unsigned int width, unsigned int height, int bpp,
float desired_coverage, float desired_coverage,
float alpha_test_threshold) float alpha_test_threshold)
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
*/ */
#include <libgimp/gimp.h> #include <libgimp/gimp.h>
#include "misc.h"
static inline float saturate(float a) static inline float saturate(float a)
{ {
...@@ -44,7 +45,7 @@ void decode_ycocg_image(gint32 drawableID, gboolean shadow) ...@@ -44,7 +45,7 @@ void decode_ycocg_image(gint32 drawableID, gboolean shadow)
if(shadow) if(shadow)
{ {
sbuffer = gimp_drawable_get_shadow_buffer(drawableID); sbuffer = gimp_drawable_get_shadow_buffer(drawableID);
gegl_buffer_copy(buffer, NULL, sbuffer, NULL); gegl_buffer_copy(buffer, NULL, GEGL_ABYSS_NONE, sbuffer, NULL);
g_object_unref(buffer); g_object_unref(buffer);
buffer = sbuffer; buffer = sbuffer;
} }
...@@ -87,7 +88,7 @@ void decode_ycocg_image(gint32 drawableID, gboolean shadow) ...@@ -87,7 +88,7 @@ void decode_ycocg_image(gint32 drawableID, gboolean shadow)
gimp_progress_update((float)i / (float)num_pixels); gimp_progress_update((float)i / (float)num_pixels);
} }
gegl_buffer_set(buffer, GEGL_RECTANGLE(0, 0, w, h), 1.0, format, data, gegl_buffer_set(buffer, GEGL_RECTANGLE(0, 0, w, h), 0, format, data,
GEGL_AUTO_ROWSTRIDE); GEGL_AUTO_ROWSTRIDE);
gimp_progress_update(1.0); gimp_progress_update(1.0);
...@@ -119,7 +120,7 @@ void decode_ycocg_scaled_image(gint32 drawableID, gboolean shadow) ...@@ -119,7 +120,7 @@ void decode_ycocg_scaled_image(gint32 drawableID, gboolean shadow)
if(shadow) if(shadow)
{ {
sbuffer = gimp_drawable_get_shadow_buffer(drawableID); sbuffer = gimp_drawable_get_shadow_buffer(drawableID);
gegl_buffer_copy(buffer, NULL, sbuffer, NULL); gegl_buffer_copy(buffer, NULL, GEGL_ABYSS_NONE, sbuffer, NULL);
g_object_unref(buffer); g_object_unref(buffer);
buffer = sbuffer; buffer = sbuffer;
} }
...@@ -165,7 +166,7 @@ void decode_ycocg_scaled_image(gint32 drawableID, gboolean shadow) ...@@ -165,7 +166,7 @@ void decode_ycocg_scaled_image(gint32 drawableID, gboolean shadow)
gimp_progress_update((float)i / (float)num_pixels); gimp_progress_update((float)i / (float)num_pixels);
} }
gegl_buffer_set(buffer, GEGL_RECTANGLE(0, 0, w, h), 1.0, format, data, gegl_buffer_set(buffer, GEGL_RECTANGLE(0, 0, w, h), 0, format, data,
GEGL_AUTO_ROWSTRIDE); GEGL_AUTO_ROWSTRIDE);
gimp_progress_update(1.0); gimp_progress_update(1.0);
...@@ -195,7 +196,7 @@ void decode_alpha_exp_image(gint32 drawableID, gboolean shadow) ...@@ -195,7 +196,7 @@ void decode_alpha_exp_image(gint32 drawableID, gboolean shadow)
if(shadow) if(shadow)
{ {
sbuffer = gimp_drawable_get_shadow_buffer(drawableID); sbuffer = gimp_drawable_get_shadow_buffer(drawableID);
gegl_buffer_copy(buffer, NULL, sbuffer, NULL); gegl_buffer_copy(buffer, NULL, GEGL_ABYSS_NONE, sbuffer, NULL);
g_object_unref(buffer); g_object_unref(buffer);
buffer = sbuffer; buffer = sbuffer;
} }
...@@ -234,7 +235,7 @@ void decode_alpha_exp_image(gint32 drawableID, gboolean shadow) ...@@ -234,7 +235,7 @@ void decode_alpha_exp_image(gint32 drawableID, gboolean shadow)
gimp_progress_update((float)i / (float)num_pixels); gimp_progress_update((float)i / (float)num_pixels);
} }
gegl_buffer_set(buffer, GEGL_RECTANGLE(0, 0, w, h), 1.0, format, data, gegl_buffer_set(buffer, GEGL_RECTANGLE(0, 0, w, h), 0, format, data,
GEGL_AUTO_ROWSTRIDE); GEGL_AUTO_ROWSTRIDE);
gimp_progress_update(1.0); gimp_progress_update(1.0);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment