Update upstream
This commit is contained in:
@ -42,10 +42,6 @@
|
||||
#define LOAD_PROC "file-dds-load"
|
||||
#define SAVE_PROC "file-dds-save"
|
||||
|
||||
#define DECODE_YCOCG_PROC "color-decode-ycocg"
|
||||
#define DECODE_YCOCG_SCALED_PROC "color-decode-ycocg-scaled"
|
||||
#define DECODE_ALPHA_EXP_PROC "color-decode-alpha-exp"
|
||||
|
||||
|
||||
typedef struct _Dds Dds;
|
||||
typedef struct _DdsClass DdsClass;
|
||||
@ -86,15 +82,6 @@ static PikaValueArray * dds_save (PikaProcedure *procedure,
|
||||
PikaMetadata *metadata,
|
||||
PikaProcedureConfig *config,
|
||||
gpointer run_data);
|
||||
#if 0
|
||||
static PikaValueArray * dds_decode (PikaProcedure *procedure,
|
||||
PikaRunMode run_mode,
|
||||
PikaImage *image,
|
||||
gint n_drawables,
|
||||
PikaDrawable **drawables,
|
||||
PikaProcedureConfig *config,
|
||||
gpointer run_data);
|
||||
#endif
|
||||
|
||||
|
||||
G_DEFINE_TYPE (Dds, dds, PIKA_TYPE_PLUG_IN)
|
||||
@ -125,11 +112,6 @@ dds_query_procedures (PikaPlugIn *plug_in)
|
||||
|
||||
list = g_list_append (list, g_strdup (LOAD_PROC));
|
||||
list = g_list_append (list, g_strdup (SAVE_PROC));
|
||||
#if 0
|
||||
list = g_list_append (list, g_strdup (DECODE_YCOCG_PROC));
|
||||
list = g_list_append (list, g_strdup (DECODE_YCOCG_SCALED_PROC));
|
||||
list = g_list_append (list, g_strdup (DECODE_ALPHA_EXP_PROC));
|
||||
#endif
|
||||
|
||||
return list;
|
||||
}
|
||||
@ -170,10 +152,10 @@ dds_create_procedure (PikaPlugIn *plug_in,
|
||||
TRUE,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
PIKA_PROC_ARG_BOOLEAN (procedure, "decode-images",
|
||||
_("Automatically decode YCoCg/AE_xp images when detected"),
|
||||
_("Decode YCoCg/AExp images when detected"),
|
||||
TRUE,
|
||||
PIKA_PROC_ARG_BOOLEAN (procedure, "flip-image",
|
||||
_("Flip image _vertically"),
|
||||
_("Flip the image vertically on import"),
|
||||
FALSE,
|
||||
G_PARAM_READWRITE);
|
||||
}
|
||||
else if (! strcmp (name, SAVE_PROC))
|
||||
@ -249,13 +231,17 @@ dds_create_procedure (PikaPlugIn *plug_in,
|
||||
"default",
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
PIKA_PROC_ARG_INT (procedure, "save-type",
|
||||
"Save type",
|
||||
"How to save the image (0 = selected layer, "
|
||||
"1 = cube map, 2 = volume map, 3 = texture array, "
|
||||
"4 = all visible layers)",
|
||||
0, 4, DDS_SAVE_SELECTED_LAYER,
|
||||
G_PARAM_READWRITE);
|
||||
PIKA_PROC_ARG_CHOICE (procedure, "save-type",
|
||||
_("Sav_e type"),
|
||||
_("How to save the image"),
|
||||
pika_choice_new_with_values ("layer", DDS_SAVE_SELECTED_LAYER, _("Selected layer"), NULL,
|
||||
"canvas", DDS_SAVE_VISIBLE_LAYERS, _("All visible layers"), NULL,
|
||||
"cube", DDS_SAVE_CUBEMAP, _("As cube map"), NULL,
|
||||
"volume", DDS_SAVE_VOLUMEMAP, _("As volume map"), NULL,
|
||||
"array", DDS_SAVE_ARRAY, _("As texture array"), NULL,
|
||||
NULL),
|
||||
"layer",
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
PIKA_PROC_ARG_BOOLEAN (procedure, "flip-image",
|
||||
_("Flip image _vertically on export"),
|
||||
@ -276,26 +262,29 @@ dds_create_procedure (PikaPlugIn *plug_in,
|
||||
0, 255, 0,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
PIKA_PROC_ARG_INT (procedure, "mipmaps",
|
||||
"Mipmaps",
|
||||
"How to handle mipmaps (0 = No mipmaps, "
|
||||
"1 = Generate mipmaps, "
|
||||
"2 = Use existing mipmaps (layers)",
|
||||
0, 2, DDS_MIPMAP_NONE,
|
||||
G_PARAM_READWRITE);
|
||||
PIKA_PROC_ARG_CHOICE (procedure, "mipmaps",
|
||||
_("_Mipmaps"),
|
||||
_("How to handle mipmaps"),
|
||||
pika_choice_new_with_values ("none", DDS_MIPMAP_NONE, _("No mipmaps"), NULL,
|
||||
"generate", DDS_MIPMAP_GENERATE, _("Generate mipmaps"), NULL,
|
||||
"existing", DDS_MIPMAP_EXISTING, _("Use existing mipmaps"), NULL,
|
||||
NULL),
|
||||
"none",
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
PIKA_PROC_ARG_CHOICE (procedure, "mipmap-filter",
|
||||
_("F_ilter"),
|
||||
_("Filtering to use when generating mipmaps"),
|
||||
pika_choice_new_with_values ("default", DDS_MIPMAP_FILTER_DEFAULT, _("Default"), NULL,
|
||||
"nearest", DDS_MIPMAP_FILTER_NEAREST, _("Nearest"), NULL,
|
||||
"box", DDS_MIPMAP_FILTER_BOX, _("Box"), NULL,
|
||||
"triangle", DDS_MIPMAP_FILTER_TRIANGLE, _("Triangle"), NULL,
|
||||
"quadratic", DDS_MIPMAP_FILTER_QUADRATIC, _("Quadratic"), NULL,
|
||||
"bspline", DDS_MIPMAP_FILTER_BSPLINE, _("B-Spline"), NULL,
|
||||
"mitchell", DDS_MIPMAP_FILTER_MITCHELL, _("Mitchell"), NULL,
|
||||
"lanczos", DDS_MIPMAP_FILTER_LANCZOS, _("Lanczos"), NULL,
|
||||
"kaiser", DDS_MIPMAP_FILTER_KAISER, _("Kaiser"), NULL,
|
||||
pika_choice_new_with_values ("default", DDS_MIPMAP_FILTER_DEFAULT, _("Default"), NULL,
|
||||
"nearest", DDS_MIPMAP_FILTER_NEAREST, _("Nearest"), NULL,
|
||||
"box", DDS_MIPMAP_FILTER_BOX, _("Box"), NULL,
|
||||
"triangle", DDS_MIPMAP_FILTER_TRIANGLE, _("Triangle"), NULL,
|
||||
"quadratic", DDS_MIPMAP_FILTER_QUADRATIC, _("Quadratic"), NULL,
|
||||
"bspline", DDS_MIPMAP_FILTER_BSPLINE, _("B-Spline"), NULL,
|
||||
"mitchell", DDS_MIPMAP_FILTER_MITCHELL, _("Mitchell"), NULL,
|
||||
"catrom", DDS_MIPMAP_FILTER_CATROM, _("Catmull-Rom"), NULL,
|
||||
"lanczos", DDS_MIPMAP_FILTER_LANCZOS, _("Lanczos"), NULL,
|
||||
"kaiser", DDS_MIPMAP_FILTER_KAISER, _("Kaiser"), NULL,
|
||||
NULL),
|
||||
"default",
|
||||
G_PARAM_READWRITE);
|
||||
@ -343,78 +332,6 @@ dds_create_procedure (PikaPlugIn *plug_in,
|
||||
0.0, 1.0, 0.5,
|
||||
G_PARAM_READWRITE);
|
||||
}
|
||||
#if 0
|
||||
else if (! strcmp (name, DECODE_YCOCG_PROC))
|
||||
{
|
||||
procedure = pika_image_procedure_new (plug_in, name,
|
||||
PIKA_PDB_PROC_TYPE_PLUGIN,
|
||||
dds_decode, NULL, NULL);
|
||||
|
||||
pika_procedure_set_image_types (procedure, "RGBA");
|
||||
pika_procedure_set_sensitivity_mask (procedure,
|
||||
PIKA_PROCEDURE_SENSITIVE_DRAWABLE);
|
||||
|
||||
pika_procedure_set_menu_label (procedure, _("Decode YCoCg"));
|
||||
/* pika_procedure_add_menu_path (procedure, "<Image>/Filters/Colors"); */
|
||||
|
||||
pika_procedure_set_documentation (procedure,
|
||||
_("Converts YCoCg encoded pixels to RGB"),
|
||||
_("Converts YCoCg encoded pixels to RGB"),
|
||||
name);
|
||||
pika_procedure_set_attribution (procedure,
|
||||
"Shawn Kirst",
|
||||
"Shawn Kirst",
|
||||
"2008");
|
||||
}
|
||||
else if (! strcmp (name, DECODE_YCOCG_SCALED_PROC))
|
||||
{
|
||||
procedure = pika_image_procedure_new (plug_in, name,
|
||||
PIKA_PDB_PROC_TYPE_PLUGIN,
|
||||
dds_decode, NULL, NULL);
|
||||
|
||||
pika_procedure_set_image_types (procedure, "RGBA");
|
||||
pika_procedure_set_sensitivity_mask (procedure,
|
||||
PIKA_PROCEDURE_SENSITIVE_DRAWABLE);
|
||||
|
||||
pika_procedure_set_menu_label (procedure, _("Decode YCoCg (scaled)"));
|
||||
/* pika_procedure_add_menu_path (procedure, "<Image>/Filters/Colors"); */
|
||||
|
||||
pika_procedure_set_documentation (procedure,
|
||||
_("Converts YCoCg (scaled) encoded "
|
||||
"pixels to RGB"),
|
||||
_("Converts YCoCg (scaled) encoded "
|
||||
"pixels to RGB"),
|
||||
name);
|
||||
pika_procedure_set_attribution (procedure,
|
||||
"Shawn Kirst",
|
||||
"Shawn Kirst",
|
||||
"2008");
|
||||
}
|
||||
else if (! strcmp (name, DECODE_ALPHA_EXP_PROC))
|
||||
{
|
||||
procedure = pika_image_procedure_new (plug_in, name,
|
||||
PIKA_PDB_PROC_TYPE_PLUGIN,
|
||||
dds_decode, NULL, NULL);
|
||||
|
||||
pika_procedure_set_image_types (procedure, "RGBA");
|
||||
pika_procedure_set_sensitivity_mask (procedure,
|
||||
PIKA_PROCEDURE_SENSITIVE_DRAWABLE);
|
||||
|
||||
pika_procedure_set_menu_label (procedure, _("Decode Alpha exponent"));
|
||||
/* pika_procedure_add_menu_path (procedure, "<Image>/Filters/Colors"); */
|
||||
|
||||
pika_procedure_set_documentation (procedure,
|
||||
_("Converts alpha exponent encoded "
|
||||
"pixels to RGB",
|
||||
_("Converts alpha exponent encoded "
|
||||
"pixels to RGB"),
|
||||
name);
|
||||
pika_procedure_set_attribution (procedure,
|
||||
"Shawn Kirst",
|
||||
"Shawn Kirst",
|
||||
"2008");
|
||||
}
|
||||
#endif
|
||||
|
||||
return procedure;
|
||||
}
|
||||
@ -436,7 +353,7 @@ dds_load (PikaProcedure *procedure,
|
||||
gegl_init (NULL, NULL);
|
||||
|
||||
status = read_dds (file, &image, run_mode == PIKA_RUN_INTERACTIVE,
|
||||
procedure, G_OBJECT (config), &error);
|
||||
procedure, config, &error);
|
||||
|
||||
if (status != PIKA_PDB_SUCCESS)
|
||||
return pika_procedure_new_return_values (procedure, status, error);
|
||||
@ -520,53 +437,3 @@ dds_save (PikaProcedure *procedure,
|
||||
|
||||
return pika_procedure_new_return_values (procedure, status, error);
|
||||
}
|
||||
|
||||
#if 0
|
||||
static PikaValueArray *
|
||||
dds_decode (PikaProcedure *procedure,
|
||||
PikaRunMode run_mode,
|
||||
PikaImage *image,
|
||||
gint n_drawables,
|
||||
PikaDrawable **drawables,
|
||||
PikaProcedureConfig *config,
|
||||
gpointer run_data)
|
||||
{
|
||||
const gchar *name = pika_procedure_get_name (procedure);
|
||||
PikaDrawable *drawable,
|
||||
|
||||
if (n_drawables != 1)
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
||||
g_set_error (&error, PIKA_PLUG_IN_ERROR, 0,
|
||||
_("Procedure '%s' only works with one drawable."),
|
||||
name);
|
||||
|
||||
return pika_procedure_new_return_values (procedure,
|
||||
PIKA_PDB_EXECUTION_ERROR,
|
||||
error);
|
||||
}
|
||||
else
|
||||
{
|
||||
drawable = drawables[0];
|
||||
}
|
||||
|
||||
if (! strcmp (name, DECODE_YCOCG_PROC))
|
||||
{
|
||||
decode_ycocg_image (drawable, TRUE);
|
||||
}
|
||||
else if (! strcmp (name, DECODE_YCOCG_SCALED_PROC))
|
||||
{
|
||||
decode_ycocg_scaled_image (drawable, TRUE);
|
||||
}
|
||||
else if (! strcmp (name, DECODE_ALPHA_EXP_PROC))
|
||||
{
|
||||
decode_alpha_exp_image (drawable, TRUE);
|
||||
}
|
||||
|
||||
if (run_mode != PIKA_RUN_NONINTERACTIVE)
|
||||
pika_displays_flush ();
|
||||
|
||||
return pika_procedure_new_return_values (procedure, PIKA_PDB_SUCCESS, NULL);
|
||||
}
|
||||
#endif
|
||||
|
@ -21,6 +21,7 @@
|
||||
#ifndef __DDS_H__
|
||||
#define __DDS_H__
|
||||
|
||||
|
||||
#define DDS_PLUGIN_VERSION_MAJOR 3
|
||||
#define DDS_PLUGIN_VERSION_MINOR 9
|
||||
#define DDS_PLUGIN_VERSION_REVISION 92
|
||||
@ -101,6 +102,7 @@ typedef enum
|
||||
DDS_MIPMAP_FILTER_QUADRATIC,
|
||||
DDS_MIPMAP_FILTER_BSPLINE,
|
||||
DDS_MIPMAP_FILTER_MITCHELL,
|
||||
DDS_MIPMAP_FILTER_CATROM,
|
||||
DDS_MIPMAP_FILTER_LANCZOS,
|
||||
DDS_MIPMAP_FILTER_KAISER,
|
||||
DDS_MIPMAP_FILTER_MAX
|
||||
@ -115,6 +117,7 @@ typedef enum
|
||||
DDS_MIPMAP_WRAP_MAX
|
||||
} DDS_MIPMAP_WRAP;
|
||||
|
||||
|
||||
#define DDS_HEADERSIZE 128
|
||||
#define DDS_HEADERSIZE_DX10 20
|
||||
|
||||
@ -122,18 +125,43 @@ typedef enum
|
||||
#define DDSD_HEIGHT 0x00000002
|
||||
#define DDSD_WIDTH 0x00000004
|
||||
#define DDSD_PITCH 0x00000008
|
||||
#define DDSD_BACKBUFFERCOUNT 0x00000020
|
||||
#define DDSD_ZBUFFERBITDEPTH 0x00000040
|
||||
#define DDSD_ALPHABITDEPTH 0x00000080
|
||||
#define DDSD_LPSURFACE 0x00000800
|
||||
#define DDSD_PIXELFORMAT 0x00001000
|
||||
#define DDSD_CKDESTOVERLAY 0x00002000
|
||||
#define DDSD_CKDESTBLT 0x00004000
|
||||
#define DDSD_CKSRCOVERLAY 0x00008000
|
||||
#define DDSD_CKSRCBLT 0x00010000
|
||||
#define DDSD_MIPMAPCOUNT 0x00020000
|
||||
#define DDSD_REFRESHRATE 0x00040000
|
||||
#define DDSD_LINEARSIZE 0x00080000
|
||||
#define DDSD_TEXTURESTAGE 0x00100000
|
||||
#define DDSD_FVF 0x00200000
|
||||
#define DDSD_SRCVBHANDLE 0x00400000
|
||||
#define DDSD_DEPTH 0x00800000
|
||||
|
||||
#define DDPF_ALPHAPIXELS 0x00000001
|
||||
#define DDPF_ALPHA 0x00000002
|
||||
#define DDPF_FOURCC 0x00000004
|
||||
#define DDPF_PALETTEINDEXED4 0x00000008
|
||||
#define DDPF_PALETTEINDEXEDTO8 0x00000010
|
||||
#define DDPF_PALETTEINDEXED8 0x00000020
|
||||
#define DDPF_RGB 0x00000040
|
||||
#define DDPF_COMPRESSED 0x00000080
|
||||
#define DDPF_RGBTOYUV 0x00000100
|
||||
#define DDPF_YUV 0x00000200
|
||||
#define DDPF_ZBUFFER 0x00000400
|
||||
#define DDPF_PALETTEINDEXED1 0x00000800
|
||||
#define DDPF_PALETTEINDEXED2 0x00001000
|
||||
#define DDPF_ZPIXELS 0x00002000
|
||||
#define DDPF_STENCILBUFFER 0x00004000
|
||||
#define DDPF_ALPHAPREMULT 0x00008000
|
||||
#define DDPF_LUMINANCE 0x00020000
|
||||
#define DDPF_NORMAL 0x80000000 // nvidia specific
|
||||
#define DDPF_BUMPLUMINANCE 0x00040000
|
||||
#define DDPF_BUMPDUDV 0x00080000
|
||||
#define DDPF_NORMAL 0x80000000 /* NVidia specific */
|
||||
|
||||
#define DDSCAPS_COMPLEX 0x00000008
|
||||
#define DDSCAPS_TEXTURE 0x00001000
|
||||
@ -159,6 +187,7 @@ typedef enum
|
||||
#define D3D10_RESOURCE_DIMENSION_TEXTURE2D 3
|
||||
#define D3D10_RESOURCE_DIMENSION_TEXTURE3D 4
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned int size;
|
||||
@ -192,8 +221,8 @@ typedef struct
|
||||
{
|
||||
struct
|
||||
{
|
||||
unsigned int magic1; // FOURCC "PIKA"
|
||||
unsigned int magic2; // FOURCC "-DDS"
|
||||
unsigned int magic1; /* FOURCC "PIKA" */
|
||||
unsigned int magic2; /* FOURCC "-DDS" */
|
||||
unsigned int version;
|
||||
unsigned int extra_fourcc;
|
||||
} pika_dds_special;
|
||||
@ -204,6 +233,7 @@ typedef struct
|
||||
unsigned int reserved2;
|
||||
} dds_header_t;
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DXGI_FORMAT_UNKNOWN = 0,
|
||||
@ -334,4 +364,70 @@ typedef struct
|
||||
unsigned int reserved;
|
||||
} dds_header_dx10_t;
|
||||
|
||||
/* Format values that can be found in the FOURCC field */
|
||||
typedef enum _D3DFORMAT {
|
||||
D3DFMT_R8G8B8 = 20,
|
||||
D3DFMT_A8R8G8B8 = 21,
|
||||
D3DFMT_X8R8G8B8 = 22,
|
||||
D3DFMT_R5G6B5 = 23,
|
||||
D3DFMT_X1R5G5B5 = 24,
|
||||
D3DFMT_A1R5G5B5 = 25,
|
||||
D3DFMT_A4R4G4B4 = 26,
|
||||
D3DFMT_R3G3B2 = 27,
|
||||
D3DFMT_A8 = 28,
|
||||
D3DFMT_A8R3G3B2 = 29,
|
||||
D3DFMT_X4R4G4B4 = 30,
|
||||
D3DFMT_A2B10G10R10 = 31,
|
||||
D3DFMT_A8B8G8R8 = 32,
|
||||
D3DFMT_X8B8G8R8 = 33,
|
||||
D3DFMT_G16R16 = 34,
|
||||
D3DFMT_A2R10G10B10 = 35,
|
||||
D3DFMT_A16B16G16R16 = 36,
|
||||
|
||||
D3DFMT_A8P8 = 40,
|
||||
D3DFMT_P8 = 41,
|
||||
|
||||
D3DFMT_L8 = 50,
|
||||
D3DFMT_A8L8 = 51,
|
||||
D3DFMT_A4L4 = 52,
|
||||
|
||||
D3DFMT_V8U8 = 60,
|
||||
D3DFMT_L6V5U5 = 61,
|
||||
D3DFMT_X8L8V8U8 = 62,
|
||||
D3DFMT_Q8W8V8U8 = 63,
|
||||
D3DFMT_V16U16 = 64,
|
||||
D3DFMT_A2W10V10U10 = 67,
|
||||
|
||||
D3DFMT_D16_LOCKABLE = 70,
|
||||
D3DFMT_D32 = 71,
|
||||
D3DFMT_D15S1 = 73,
|
||||
D3DFMT_D24S8 = 75,
|
||||
D3DFMT_D24X8 = 77,
|
||||
D3DFMT_D24X4S4 = 79,
|
||||
D3DFMT_D16 = 80,
|
||||
D3DFMT_L16 = 81,
|
||||
D3DFMT_D32F_LOCKABLE = 82,
|
||||
D3DFMT_D24FS8 = 83,
|
||||
D3DFMT_D32_LOCKABLE = 84,
|
||||
D3DFMT_S8_LOCKABLE = 85,
|
||||
|
||||
D3DFMT_VERTEXDATA = 100,
|
||||
D3DFMT_INDEX16 = 101,
|
||||
D3DFMT_INDEX32 = 102,
|
||||
|
||||
D3DFMT_Q16W16V16U16 = 110,
|
||||
D3DFMT_R16F = 111,
|
||||
D3DFMT_G16R16F = 112,
|
||||
D3DFMT_A16B16G16R16F = 113,
|
||||
D3DFMT_R32F = 114,
|
||||
D3DFMT_G32R32F = 115,
|
||||
D3DFMT_A32B32G32R32F = 116,
|
||||
D3DFMT_CxV8U8 = 117,
|
||||
|
||||
D3DFMT_A1 = 118,
|
||||
D3DFMT_A2B10G10R10_XR_BIAS = 119,
|
||||
D3DFMT_BINARYBUFFER = 199,
|
||||
} D3DFORMAT;
|
||||
|
||||
|
||||
#endif /* __DDS_H__ */
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -22,12 +22,12 @@
|
||||
#define __DDSREAD_H__
|
||||
|
||||
|
||||
extern PikaPDBStatusType read_dds (GFile *file,
|
||||
PikaImage **image,
|
||||
gboolean interactive,
|
||||
PikaProcedure *procedure,
|
||||
GObject *config,
|
||||
GError **error);
|
||||
extern PikaPDBStatusType read_dds (GFile *file,
|
||||
PikaImage **image,
|
||||
gboolean interactive,
|
||||
PikaProcedure *procedure,
|
||||
PikaProcedureConfig *config,
|
||||
GError **error);
|
||||
|
||||
|
||||
#endif /* __DDSREAD_H__ */
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -34,11 +34,14 @@
|
||||
#include <math.h>
|
||||
#include <glib.h>
|
||||
|
||||
#include <libpika/pika.h>
|
||||
|
||||
#include "dds.h"
|
||||
#include "dxt.h"
|
||||
#include "endian_rw.h"
|
||||
#include "mipmap.h"
|
||||
#include "imath.h"
|
||||
#include "mipmap.h"
|
||||
#include "misc.h"
|
||||
#include "vec.h"
|
||||
|
||||
#include "dxt_tables.h"
|
||||
@ -757,181 +760,6 @@ encode_color_block (unsigned char *dst,
|
||||
PUTL32(dst + 4, indices);
|
||||
}
|
||||
|
||||
static void
|
||||
get_min_max_YCoCg (const unsigned char *block,
|
||||
unsigned char *mincolor,
|
||||
unsigned char *maxcolor)
|
||||
{
|
||||
int i;
|
||||
|
||||
mincolor[2] = mincolor[1] = 255;
|
||||
maxcolor[2] = maxcolor[1] = 0;
|
||||
|
||||
for (i = 0; i < 16; ++i)
|
||||
{
|
||||
if (block[4 * i + 2] < mincolor[2]) mincolor[2] = block[4 * i + 2];
|
||||
if (block[4 * i + 1] < mincolor[1]) mincolor[1] = block[4 * i + 1];
|
||||
if (block[4 * i + 2] > maxcolor[2]) maxcolor[2] = block[4 * i + 2];
|
||||
if (block[4 * i + 1] > maxcolor[1]) maxcolor[1] = block[4 * i + 1];
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
scale_YCoCg (unsigned char *block,
|
||||
unsigned char *mincolor,
|
||||
unsigned char *maxcolor)
|
||||
{
|
||||
const int s0 = 128 / 2 - 1;
|
||||
const int s1 = 128 / 4 - 1;
|
||||
int m0, m1, m2, m3;
|
||||
int mask0, mask1, scale;
|
||||
int i;
|
||||
|
||||
m0 = abs(mincolor[2] - 128);
|
||||
m1 = abs(mincolor[1] - 128);
|
||||
m2 = abs(maxcolor[2] - 128);
|
||||
m3 = abs(maxcolor[1] - 128);
|
||||
|
||||
if (m1 > m0) m0 = m1;
|
||||
if (m3 > m2) m2 = m3;
|
||||
if (m2 > m0) m0 = m2;
|
||||
|
||||
mask0 = -(m0 <= s0);
|
||||
mask1 = -(m0 <= s1);
|
||||
scale = 1 + (1 & mask0) + (2 & mask1);
|
||||
|
||||
mincolor[2] = (mincolor[2] - 128) * scale + 128;
|
||||
mincolor[1] = (mincolor[1] - 128) * scale + 128;
|
||||
mincolor[0] = (scale - 1) << 3;
|
||||
|
||||
maxcolor[2] = (maxcolor[2] - 128) * scale + 128;
|
||||
maxcolor[1] = (maxcolor[1] - 128) * scale + 128;
|
||||
maxcolor[0] = (scale - 1) << 3;
|
||||
|
||||
for (i = 0; i < 16; ++i)
|
||||
{
|
||||
block[i * 4 + 2] = (block[i * 4 + 2] - 128) * scale + 128;
|
||||
block[i * 4 + 1] = (block[i * 4 + 1] - 128) * scale + 128;
|
||||
}
|
||||
}
|
||||
|
||||
#define INSET_SHIFT 4
|
||||
|
||||
static void
|
||||
inset_bbox_YCoCg (unsigned char *mincolor,
|
||||
unsigned char *maxcolor)
|
||||
{
|
||||
int inset[4], mini[4], maxi[4];
|
||||
|
||||
inset[2] = (maxcolor[2] - mincolor[2]) - ((1 << (INSET_SHIFT - 1)) - 1);
|
||||
inset[1] = (maxcolor[1] - mincolor[1]) - ((1 << (INSET_SHIFT - 1)) - 1);
|
||||
|
||||
mini[2] = ((mincolor[2] << INSET_SHIFT) + inset[2]) >> INSET_SHIFT;
|
||||
mini[1] = ((mincolor[1] << INSET_SHIFT) + inset[1]) >> INSET_SHIFT;
|
||||
|
||||
maxi[2] = ((maxcolor[2] << INSET_SHIFT) - inset[2]) >> INSET_SHIFT;
|
||||
maxi[1] = ((maxcolor[1] << INSET_SHIFT) - inset[1]) >> INSET_SHIFT;
|
||||
|
||||
mini[2] = (mini[2] >= 0) ? mini[2] : 0;
|
||||
mini[1] = (mini[1] >= 0) ? mini[1] : 0;
|
||||
|
||||
maxi[2] = (maxi[2] <= 255) ? maxi[2] : 255;
|
||||
maxi[1] = (maxi[1] <= 255) ? maxi[1] : 255;
|
||||
|
||||
mincolor[2] = (mini[2] & 0xf8) | (mini[2] >> 5);
|
||||
mincolor[1] = (mini[1] & 0xfc) | (mini[1] >> 6);
|
||||
|
||||
maxcolor[2] = (maxi[2] & 0xf8) | (maxi[2] >> 5);
|
||||
maxcolor[1] = (maxi[1] & 0xfc) | (maxi[1] >> 6);
|
||||
}
|
||||
|
||||
static void
|
||||
select_diagonal_YCoCg (const unsigned char *block,
|
||||
unsigned char *mincolor,
|
||||
unsigned char *maxcolor)
|
||||
{
|
||||
unsigned char mid0, mid1, side, mask, b0, b1, c0, c1;
|
||||
int i;
|
||||
|
||||
mid0 = ((int)mincolor[2] + maxcolor[2] + 1) >> 1;
|
||||
mid1 = ((int)mincolor[1] + maxcolor[1] + 1) >> 1;
|
||||
|
||||
side = 0;
|
||||
for (i = 0; i < 16; ++i)
|
||||
{
|
||||
b0 = block[i * 4 + 2] >= mid0;
|
||||
b1 = block[i * 4 + 1] >= mid1;
|
||||
side += (b0 ^ b1);
|
||||
}
|
||||
|
||||
mask = -(side > 8);
|
||||
mask &= -(mincolor[2] != maxcolor[2]);
|
||||
|
||||
c0 = mincolor[1];
|
||||
c1 = maxcolor[1];
|
||||
|
||||
c0 ^= c1;
|
||||
c1 ^= c0 & mask;
|
||||
c0 ^= c1;
|
||||
|
||||
mincolor[1] = c0;
|
||||
maxcolor[1] = c1;
|
||||
}
|
||||
|
||||
static void
|
||||
encode_YCoCg_block (unsigned char *dst,
|
||||
unsigned char *block)
|
||||
{
|
||||
unsigned char colors[4][3], *maxcolor, *mincolor;
|
||||
unsigned int mask;
|
||||
int c0, c1, d0, d1, d2, d3;
|
||||
int b0, b1, b2, b3, b4;
|
||||
int x0, x1, x2;
|
||||
int i, idx;
|
||||
|
||||
maxcolor = &colors[0][0];
|
||||
mincolor = &colors[1][0];
|
||||
|
||||
get_min_max_YCoCg(block, mincolor, maxcolor);
|
||||
scale_YCoCg(block, mincolor, maxcolor);
|
||||
inset_bbox_YCoCg(mincolor, maxcolor);
|
||||
select_diagonal_YCoCg(block, mincolor, maxcolor);
|
||||
|
||||
lerp_rgb13(&colors[2][0], maxcolor, mincolor);
|
||||
lerp_rgb13(&colors[3][0], mincolor, maxcolor);
|
||||
|
||||
mask = 0;
|
||||
|
||||
for (i = 0; i < 16; ++i)
|
||||
{
|
||||
c0 = block[4 * i + 2];
|
||||
c1 = block[4 * i + 1];
|
||||
|
||||
d0 = abs(colors[0][2] - c0) + abs(colors[0][1] - c1);
|
||||
d1 = abs(colors[1][2] - c0) + abs(colors[1][1] - c1);
|
||||
d2 = abs(colors[2][2] - c0) + abs(colors[2][1] - c1);
|
||||
d3 = abs(colors[3][2] - c0) + abs(colors[3][1] - c1);
|
||||
|
||||
b0 = d0 > d3;
|
||||
b1 = d1 > d2;
|
||||
b2 = d0 > d2;
|
||||
b3 = d1 > d3;
|
||||
b4 = d2 > d3;
|
||||
|
||||
x0 = b1 & b2;
|
||||
x1 = b0 & b3;
|
||||
x2 = b0 & b4;
|
||||
|
||||
idx = (x2 | ((x0 | x1) << 1));
|
||||
|
||||
mask |= idx << (2 * i);
|
||||
}
|
||||
|
||||
PUTL16(dst + 0, pack_rgb565(maxcolor));
|
||||
PUTL16(dst + 2, pack_rgb565(mincolor));
|
||||
PUTL32(dst + 4, mask);
|
||||
}
|
||||
|
||||
/* write DXT3 alpha block */
|
||||
static void
|
||||
encode_alpha_block_BC2 (unsigned char *dst,
|
||||
@ -1288,33 +1116,35 @@ dxt_compress (unsigned char *dst,
|
||||
}
|
||||
|
||||
static void
|
||||
decode_color_block (unsigned char *block,
|
||||
unsigned char *src,
|
||||
int format)
|
||||
decode_color_block (guchar *block,
|
||||
guchar *src,
|
||||
gint format)
|
||||
{
|
||||
int i, x, y;
|
||||
unsigned char *d = block;
|
||||
unsigned int indices, idx;
|
||||
unsigned char colors[4][3];
|
||||
unsigned short c0, c1;
|
||||
guchar *d = block;
|
||||
guint indices, idx;
|
||||
guchar colors[4][3];
|
||||
gushort c0, c1;
|
||||
gint i, x, y;
|
||||
|
||||
c0 = GETL16(&src[0]);
|
||||
c1 = GETL16(&src[2]);
|
||||
c0 = GETL16 (&src[0]);
|
||||
c1 = GETL16 (&src[2]);
|
||||
|
||||
unpack_rgb565(colors[0], c0);
|
||||
unpack_rgb565(colors[1], c1);
|
||||
unpack_rgb565 (colors[0], c0);
|
||||
unpack_rgb565 (colors[1], c1);
|
||||
|
||||
if ((c0 > c1) || (format == DDS_COMPRESS_BC3))
|
||||
{
|
||||
lerp_rgb13(colors[2], colors[0], colors[1]);
|
||||
lerp_rgb13(colors[3], colors[1], colors[0]);
|
||||
/* Four-color mode */
|
||||
lerp_rgb13 (colors[2], colors[0], colors[1]);
|
||||
lerp_rgb13 (colors[3], colors[1], colors[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Three-color mode */
|
||||
for (i = 0; i < 3; ++i)
|
||||
{
|
||||
colors[2][i] = (colors[0][i] + colors[1][i] + 1) >> 1;
|
||||
colors[3][i] = 255;
|
||||
colors[3][i] = 0; /* Three-color mode index 11 is always black */
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,6 @@ plugin_name = 'file-dds'
|
||||
|
||||
plugin_sources = [
|
||||
'dds.c',
|
||||
'color.c',
|
||||
'ddsread.c',
|
||||
'ddswrite.c',
|
||||
'dxt.c',
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -21,55 +21,56 @@
|
||||
#ifndef __MIPMAP_H__
|
||||
#define __MIPMAP_H__
|
||||
|
||||
int get_num_mipmaps (int width,
|
||||
int height);
|
||||
unsigned int get_mipmapped_size (int width,
|
||||
int height,
|
||||
int bpp,
|
||||
int level,
|
||||
int num,
|
||||
int format);
|
||||
unsigned int get_volume_mipmapped_size (int width,
|
||||
int height,
|
||||
int depth,
|
||||
int bpp,
|
||||
int level,
|
||||
int num,
|
||||
int format);
|
||||
int get_next_mipmap_dimensions (int *next_w,
|
||||
int *next_h,
|
||||
int curr_w,
|
||||
int curr_h);
|
||||
|
||||
float cubic_interpolate (float a,
|
||||
float b,
|
||||
float c,
|
||||
float d,
|
||||
float x);
|
||||
int generate_mipmaps (unsigned char *dst,
|
||||
unsigned char *src,
|
||||
unsigned int width,
|
||||
unsigned int height,
|
||||
int bpp,
|
||||
int indexed,
|
||||
int mipmaps,
|
||||
int filter,
|
||||
int wrap,
|
||||
int gamma_correct,
|
||||
float gamma,
|
||||
int preserve_alpha_test_coverage,
|
||||
float alpha_test_threshold);
|
||||
int generate_volume_mipmaps (unsigned char *dst,
|
||||
unsigned char *src,
|
||||
unsigned int width,
|
||||
unsigned int height,
|
||||
unsigned int depth,
|
||||
int bpp,
|
||||
int indexed,
|
||||
int mipmaps,
|
||||
int filter,
|
||||
int wrap,
|
||||
int gamma_correct,
|
||||
float gamma);
|
||||
gint get_num_mipmaps (gint width,
|
||||
gint height);
|
||||
|
||||
guint get_mipmapped_size (gint width,
|
||||
gint height,
|
||||
gint bpp,
|
||||
gint level,
|
||||
gint num,
|
||||
gint format);
|
||||
|
||||
guint get_volume_mipmapped_size (gint width,
|
||||
gint height,
|
||||
gint depth,
|
||||
gint bpp,
|
||||
gint level,
|
||||
gint num,
|
||||
gint format);
|
||||
|
||||
gint get_next_mipmap_dimensions (gint *next_w,
|
||||
gint *next_h,
|
||||
gint curr_w,
|
||||
gint curr_h);
|
||||
|
||||
gint generate_mipmaps (guchar *dst,
|
||||
guchar *src,
|
||||
guint width,
|
||||
guint height,
|
||||
gint bpp,
|
||||
gint indexed,
|
||||
gint mipmaps,
|
||||
gint filter,
|
||||
gint wrap,
|
||||
gint gamma_correct,
|
||||
gfloat gamma,
|
||||
gint preserve_alpha_test_coverage,
|
||||
gfloat alpha_test_threshold);
|
||||
|
||||
gint generate_volume_mipmaps (guchar *dst,
|
||||
guchar *src,
|
||||
guint width,
|
||||
guint height,
|
||||
guint depth,
|
||||
gint bpp,
|
||||
gint indexed,
|
||||
gint mipmaps,
|
||||
gint filter,
|
||||
gint wrap,
|
||||
gint gamma_correct,
|
||||
gfloat gamma);
|
||||
|
||||
|
||||
#endif /* __MIPMAP_H__ */
|
||||
|
@ -4,56 +4,53 @@
|
||||
* Copyright (C) 2004-2012 Shawn Kirst <skirst@gmail.com>,
|
||||
* with parts (C) 2003 Arne Reuter <homepage@arnereuter.de> where specified.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301, USA.
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <libpika/pika.h>
|
||||
|
||||
#include "endian_rw.h"
|
||||
#include "imath.h"
|
||||
#include "misc.h"
|
||||
|
||||
static inline float
|
||||
saturate (float a)
|
||||
{
|
||||
if(a < 0) a = 0;
|
||||
if(a > 1) a = 1;
|
||||
|
||||
/*
|
||||
* Decoding Functions
|
||||
*/
|
||||
|
||||
static inline gfloat
|
||||
saturate (gfloat a)
|
||||
{
|
||||
if (a < 0) a = 0;
|
||||
if (a > 1) a = 1;
|
||||
return a;
|
||||
}
|
||||
|
||||
void
|
||||
decode_ycocg_image (PikaDrawable *drawable,
|
||||
gboolean shadow)
|
||||
decode_ycocg (PikaDrawable *drawable)
|
||||
{
|
||||
GeglBuffer *buffer, *sbuffer;
|
||||
const Babl *format;
|
||||
unsigned char *data;
|
||||
unsigned int i, w, h, num_pixels;
|
||||
|
||||
const float offset = 0.5f * 256.0f / 255.0f;
|
||||
float Y, Co, Cg, R, G, B;
|
||||
GeglBuffer *buffer;
|
||||
const Babl *format;
|
||||
guchar *data;
|
||||
guint num_pixels;
|
||||
guint i, w, h;
|
||||
const gfloat offset = 0.5f * 256.0f / 255.0f;
|
||||
gfloat Y, Co, Cg;
|
||||
gfloat R, G, B;
|
||||
|
||||
buffer = pika_drawable_get_buffer (drawable);
|
||||
|
||||
if (shadow)
|
||||
{
|
||||
sbuffer = pika_drawable_get_shadow_buffer (drawable);
|
||||
gegl_buffer_copy (buffer, NULL, GEGL_ABYSS_NONE, sbuffer, NULL);
|
||||
g_object_unref (buffer);
|
||||
buffer = sbuffer;
|
||||
}
|
||||
|
||||
format = babl_format ("R'G'B'A u8");
|
||||
|
||||
w = gegl_buffer_get_width (buffer);
|
||||
@ -62,46 +59,43 @@ decode_ycocg_image (PikaDrawable *drawable,
|
||||
|
||||
data = g_malloc (num_pixels * 4);
|
||||
|
||||
gegl_buffer_get (buffer, GEGL_RECTANGLE(0, 0, w, h), 1.0, format, data,
|
||||
gegl_buffer_get (buffer, GEGL_RECTANGLE (0, 0, w, h), 1.0, format, data,
|
||||
GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
|
||||
|
||||
pika_progress_init ("Decoding YCoCg pixels...");
|
||||
|
||||
for (i = 0; i < num_pixels; ++i)
|
||||
{
|
||||
Y = (float)data[4 * i + 3] / 255.0f;
|
||||
Co = (float)data[4 * i + 0] / 255.0f;
|
||||
Cg = (float)data[4 * i + 1] / 255.0f;
|
||||
Y = (gfloat) data[4 * i + 3] / 255.0f;
|
||||
Co = (gfloat) data[4 * i + 0] / 255.0f;
|
||||
Cg = (gfloat) data[4 * i + 1] / 255.0f;
|
||||
|
||||
/* convert YCoCg to RGB */
|
||||
Co -= offset;
|
||||
Cg -= offset;
|
||||
|
||||
R = saturate(Y + Co - Cg);
|
||||
G = saturate(Y + Cg);
|
||||
B = saturate(Y - Co - Cg);
|
||||
R = saturate (Y + Co - Cg);
|
||||
G = saturate (Y + Cg);
|
||||
B = saturate (Y - Co - Cg);
|
||||
|
||||
/* copy new alpha from blue */
|
||||
data[4 * i + 3] = data[4 * i + 2];
|
||||
|
||||
data[4 * i + 0] = (unsigned char)(R * 255.0f);
|
||||
data[4 * i + 1] = (unsigned char)(G * 255.0f);
|
||||
data[4 * i + 2] = (unsigned char)(B * 255.0f);
|
||||
data[4 * i + 0] = (guchar) (R * 255.0f);
|
||||
data[4 * i + 1] = (guchar) (G * 255.0f);
|
||||
data[4 * i + 2] = (guchar) (B * 255.0f);
|
||||
|
||||
if ((i & 0x7fff) == 0)
|
||||
pika_progress_update ((float)i / (float)num_pixels);
|
||||
pika_progress_update ((gdouble) i / (gdouble) num_pixels);
|
||||
}
|
||||
|
||||
gegl_buffer_set (buffer, GEGL_RECTANGLE(0, 0, w, h), 0, format, data,
|
||||
gegl_buffer_set (buffer, GEGL_RECTANGLE (0, 0, w, h), 0, format, data,
|
||||
GEGL_AUTO_ROWSTRIDE);
|
||||
|
||||
pika_progress_update (1.0);
|
||||
|
||||
gegl_buffer_flush (buffer);
|
||||
|
||||
if (shadow)
|
||||
pika_drawable_merge_shadow (drawable, TRUE);
|
||||
|
||||
pika_drawable_update (drawable, 0, 0, w, h);
|
||||
|
||||
g_free (data);
|
||||
@ -110,27 +104,19 @@ decode_ycocg_image (PikaDrawable *drawable,
|
||||
}
|
||||
|
||||
void
|
||||
decode_ycocg_scaled_image (PikaDrawable *drawable,
|
||||
gboolean shadow)
|
||||
decode_ycocg_scaled (PikaDrawable *drawable)
|
||||
{
|
||||
GeglBuffer *buffer, *sbuffer;
|
||||
const Babl *format;
|
||||
unsigned char *data;
|
||||
unsigned int i, w, h, num_pixels;
|
||||
|
||||
const float offset = 0.5f * 256.0f / 255.0f;
|
||||
float Y, Co, Cg, R, G, B, s;
|
||||
GeglBuffer *buffer;
|
||||
const Babl *format;
|
||||
guchar *data;
|
||||
guint num_pixels;
|
||||
guint i, w, h;
|
||||
const gfloat offset = 0.5f * 256.0f / 255.0f;
|
||||
gfloat Y, Co, Cg;
|
||||
gfloat R, G, B, s;
|
||||
|
||||
buffer = pika_drawable_get_buffer (drawable);
|
||||
|
||||
if (shadow)
|
||||
{
|
||||
sbuffer = pika_drawable_get_shadow_buffer (drawable);
|
||||
gegl_buffer_copy (buffer, NULL, GEGL_ABYSS_NONE, sbuffer, NULL);
|
||||
g_object_unref (buffer);
|
||||
buffer = sbuffer;
|
||||
}
|
||||
|
||||
format = babl_format ("R'G'B'A u8");
|
||||
|
||||
w = gegl_buffer_get_width (buffer);
|
||||
@ -139,17 +125,17 @@ decode_ycocg_scaled_image (PikaDrawable *drawable,
|
||||
|
||||
data = g_malloc (num_pixels * 4);
|
||||
|
||||
gegl_buffer_get (buffer, GEGL_RECTANGLE(0, 0, w, h), 1.0, format, data,
|
||||
gegl_buffer_get (buffer, GEGL_RECTANGLE (0, 0, w, h), 1.0, format, data,
|
||||
GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
|
||||
|
||||
pika_progress_init ("Decoding YCoCg (scaled) pixels...");
|
||||
|
||||
for (i = 0; i < num_pixels; ++i)
|
||||
{
|
||||
Y = (float)data[4 * i + 3] / 255.0f;
|
||||
Co = (float)data[4 * i + 0] / 255.0f;
|
||||
Cg = (float)data[4 * i + 1] / 255.0f;
|
||||
s = (float)data[4 * i + 2] / 255.0f;
|
||||
Y = (gfloat) data[4 * i + 3] / 255.0f;
|
||||
Co = (gfloat) data[4 * i + 0] / 255.0f;
|
||||
Cg = (gfloat) data[4 * i + 1] / 255.0f;
|
||||
s = (gfloat) data[4 * i + 2] / 255.0f;
|
||||
|
||||
/* convert YCoCg to RGB */
|
||||
s = 1.0f / ((255.0f / 8.0f) * s + 1.0f);
|
||||
@ -157,31 +143,28 @@ decode_ycocg_scaled_image (PikaDrawable *drawable,
|
||||
Co = (Co - offset) * s;
|
||||
Cg = (Cg - offset) * s;
|
||||
|
||||
R = saturate(Y + Co - Cg);
|
||||
G = saturate(Y + Cg);
|
||||
B = saturate(Y - Co - Cg);
|
||||
R = saturate (Y + Co - Cg);
|
||||
G = saturate (Y + Cg);
|
||||
B = saturate (Y - Co - Cg);
|
||||
|
||||
data[4 * i + 0] = (unsigned char)(R * 255.0f);
|
||||
data[4 * i + 1] = (unsigned char)(G * 255.0f);
|
||||
data[4 * i + 2] = (unsigned char)(B * 255.0f);
|
||||
data[4 * i + 0] = (guchar) (R * 255.0f);
|
||||
data[4 * i + 1] = (guchar) (G * 255.0f);
|
||||
data[4 * i + 2] = (guchar) (B * 255.0f);
|
||||
|
||||
/* set alpha to 1 */
|
||||
data[4 * i + 3] = 255;
|
||||
|
||||
if ((i & 0x7fff) == 0)
|
||||
pika_progress_update ((float)i / (float)num_pixels);
|
||||
pika_progress_update ((gdouble) i / (gdouble) num_pixels);
|
||||
}
|
||||
|
||||
gegl_buffer_set (buffer, GEGL_RECTANGLE(0, 0, w, h), 0, format, data,
|
||||
gegl_buffer_set (buffer, GEGL_RECTANGLE (0, 0, w, h), 0, format, data,
|
||||
GEGL_AUTO_ROWSTRIDE);
|
||||
|
||||
pika_progress_update (1.0);
|
||||
|
||||
gegl_buffer_flush (buffer);
|
||||
|
||||
if (shadow)
|
||||
pika_drawable_merge_shadow (drawable, TRUE);
|
||||
|
||||
pika_drawable_update (drawable, 0, 0, w, h);
|
||||
|
||||
g_free (data);
|
||||
@ -190,25 +173,17 @@ decode_ycocg_scaled_image (PikaDrawable *drawable,
|
||||
}
|
||||
|
||||
void
|
||||
decode_alpha_exp_image (PikaDrawable *drawable,
|
||||
gboolean shadow)
|
||||
decode_alpha_exponent (PikaDrawable *drawable)
|
||||
{
|
||||
GeglBuffer *buffer, *sbuffer;
|
||||
GeglBuffer *buffer;
|
||||
const Babl *format;
|
||||
unsigned char *data;
|
||||
unsigned int i, w, h, num_pixels;
|
||||
int R, G, B, A;
|
||||
guchar *data;
|
||||
guint num_pixels;
|
||||
guint i, w, h;
|
||||
gint R, G, B, A;
|
||||
|
||||
buffer = pika_drawable_get_buffer (drawable);
|
||||
|
||||
if (shadow)
|
||||
{
|
||||
sbuffer = pika_drawable_get_shadow_buffer (drawable);
|
||||
gegl_buffer_copy (buffer, NULL, GEGL_ABYSS_NONE, sbuffer, NULL);
|
||||
g_object_unref (buffer);
|
||||
buffer = sbuffer;
|
||||
}
|
||||
|
||||
format = babl_format ("R'G'B'A u8");
|
||||
|
||||
w = gegl_buffer_get_width (buffer);
|
||||
@ -217,7 +192,7 @@ decode_alpha_exp_image (PikaDrawable *drawable,
|
||||
|
||||
data = g_malloc (num_pixels * 4);
|
||||
|
||||
gegl_buffer_get (buffer, GEGL_RECTANGLE(0, 0, w, h), 1.0, format, data,
|
||||
gegl_buffer_get (buffer, GEGL_RECTANGLE (0, 0, w, h), 1.0, format, data,
|
||||
GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
|
||||
|
||||
pika_progress_init ("Decoding Alpha-exponent pixels...");
|
||||
@ -240,22 +215,268 @@ decode_alpha_exp_image (PikaDrawable *drawable,
|
||||
data[4 * i + 3] = A;
|
||||
|
||||
if ((i & 0x7fff) == 0)
|
||||
pika_progress_update ((float)i / (float)num_pixels);
|
||||
pika_progress_update ((gdouble) i / (gdouble) num_pixels);
|
||||
}
|
||||
|
||||
gegl_buffer_set (buffer, GEGL_RECTANGLE(0, 0, w, h), 0, format, data,
|
||||
gegl_buffer_set (buffer, GEGL_RECTANGLE (0, 0, w, h), 0, format, data,
|
||||
GEGL_AUTO_ROWSTRIDE);
|
||||
|
||||
pika_progress_update (1.0);
|
||||
|
||||
gegl_buffer_flush (buffer);
|
||||
|
||||
if (shadow)
|
||||
pika_drawable_merge_shadow (drawable, TRUE);
|
||||
|
||||
pika_drawable_update (drawable, 0, 0, w, h);
|
||||
|
||||
g_free (data);
|
||||
|
||||
g_object_unref (buffer);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Encoding Functions
|
||||
*/
|
||||
|
||||
void
|
||||
encode_ycocg (guchar *dst,
|
||||
gint r,
|
||||
gint g,
|
||||
gint b)
|
||||
{
|
||||
gint y = ((r + (g << 1) + b) + 2) >> 2;
|
||||
gint co = ((((r << 1) - (b << 1)) + 2) >> 2) + 128;
|
||||
gint cg = (((-r + (g << 1) - b) + 2) >> 2) + 128;
|
||||
|
||||
dst[0] = 255;
|
||||
dst[1] = (cg > 255 ? 255 : (cg < 0 ? 0 : cg));
|
||||
dst[2] = (co > 255 ? 255 : (co < 0 ? 0 : co));
|
||||
dst[3] = (y > 255 ? 255 : (y < 0 ? 0 : y));
|
||||
}
|
||||
|
||||
void
|
||||
encode_alpha_exponent (guchar *dst,
|
||||
gint r,
|
||||
gint g,
|
||||
gint b,
|
||||
gint a)
|
||||
{
|
||||
gfloat ar, ag, ab, aa;
|
||||
|
||||
ar = (gfloat) r / 255.0f;
|
||||
ag = (gfloat) g / 255.0f;
|
||||
ab = (gfloat) b / 255.0f;
|
||||
|
||||
aa = MAX (ar, MAX (ag, ab));
|
||||
|
||||
if (aa < 1e-04f)
|
||||
{
|
||||
dst[0] = b;
|
||||
dst[1] = g;
|
||||
dst[2] = r;
|
||||
dst[3] = 255;
|
||||
return;
|
||||
}
|
||||
|
||||
ar /= aa;
|
||||
ag /= aa;
|
||||
ab /= aa;
|
||||
|
||||
r = (gint) floorf (255.0f * ar + 0.5f);
|
||||
g = (gint) floorf (255.0f * ag + 0.5f);
|
||||
b = (gint) floorf (255.0f * ab + 0.5f);
|
||||
a = (gint) floorf (255.0f * aa + 0.5f);
|
||||
|
||||
dst[0] = MAX (0, MIN (255, b));
|
||||
dst[1] = MAX (0, MIN (255, g));
|
||||
dst[2] = MAX (0, MIN (255, r));
|
||||
dst[3] = MAX (0, MIN (255, a));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Compression Functions
|
||||
*/
|
||||
|
||||
static void
|
||||
get_min_max_YCoCg (const guchar *block,
|
||||
guchar *mincolor,
|
||||
guchar *maxcolor)
|
||||
{
|
||||
gint i;
|
||||
|
||||
mincolor[2] = mincolor[1] = 255;
|
||||
maxcolor[2] = maxcolor[1] = 0;
|
||||
|
||||
for (i = 0; i < 16; ++i)
|
||||
{
|
||||
if (block[4 * i + 2] < mincolor[2]) mincolor[2] = block[4 * i + 2];
|
||||
if (block[4 * i + 1] < mincolor[1]) mincolor[1] = block[4 * i + 1];
|
||||
if (block[4 * i + 2] > maxcolor[2]) maxcolor[2] = block[4 * i + 2];
|
||||
if (block[4 * i + 1] > maxcolor[1]) maxcolor[1] = block[4 * i + 1];
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
scale_YCoCg (guchar *block,
|
||||
guchar *mincolor,
|
||||
guchar *maxcolor)
|
||||
{
|
||||
const gint s0 = 128 / 2 - 1;
|
||||
const gint s1 = 128 / 4 - 1;
|
||||
gint m0, m1, m2, m3;
|
||||
gint mask0, mask1, scale;
|
||||
gint i;
|
||||
|
||||
m0 = abs (mincolor[2] - 128);
|
||||
m1 = abs (mincolor[1] - 128);
|
||||
m2 = abs (maxcolor[2] - 128);
|
||||
m3 = abs (maxcolor[1] - 128);
|
||||
|
||||
if (m1 > m0) m0 = m1;
|
||||
if (m3 > m2) m2 = m3;
|
||||
if (m2 > m0) m0 = m2;
|
||||
|
||||
mask0 = -(m0 <= s0);
|
||||
mask1 = -(m0 <= s1);
|
||||
scale = 1 + (1 & mask0) + (2 & mask1);
|
||||
|
||||
mincolor[2] = (mincolor[2] - 128) * scale + 128;
|
||||
mincolor[1] = (mincolor[1] - 128) * scale + 128;
|
||||
mincolor[0] = (scale - 1) << 3;
|
||||
|
||||
maxcolor[2] = (maxcolor[2] - 128) * scale + 128;
|
||||
maxcolor[1] = (maxcolor[1] - 128) * scale + 128;
|
||||
maxcolor[0] = (scale - 1) << 3;
|
||||
|
||||
for (i = 0; i < 16; ++i)
|
||||
{
|
||||
block[i * 4 + 2] = (block[i * 4 + 2] - 128) * scale + 128;
|
||||
block[i * 4 + 1] = (block[i * 4 + 1] - 128) * scale + 128;
|
||||
}
|
||||
}
|
||||
|
||||
#define INSET_SHIFT 4
|
||||
|
||||
static void
|
||||
inset_bbox_YCoCg (guchar *mincolor,
|
||||
guchar *maxcolor)
|
||||
{
|
||||
gint inset[4], mini[4], maxi[4];
|
||||
|
||||
inset[2] = (maxcolor[2] - mincolor[2]) - ((1 << (INSET_SHIFT - 1)) - 1);
|
||||
inset[1] = (maxcolor[1] - mincolor[1]) - ((1 << (INSET_SHIFT - 1)) - 1);
|
||||
|
||||
mini[2] = ((mincolor[2] << INSET_SHIFT) + inset[2]) >> INSET_SHIFT;
|
||||
mini[1] = ((mincolor[1] << INSET_SHIFT) + inset[1]) >> INSET_SHIFT;
|
||||
|
||||
maxi[2] = ((maxcolor[2] << INSET_SHIFT) - inset[2]) >> INSET_SHIFT;
|
||||
maxi[1] = ((maxcolor[1] << INSET_SHIFT) - inset[1]) >> INSET_SHIFT;
|
||||
|
||||
mini[2] = (mini[2] >= 0) ? mini[2] : 0;
|
||||
mini[1] = (mini[1] >= 0) ? mini[1] : 0;
|
||||
|
||||
maxi[2] = (maxi[2] <= 255) ? maxi[2] : 255;
|
||||
maxi[1] = (maxi[1] <= 255) ? maxi[1] : 255;
|
||||
|
||||
mincolor[2] = (mini[2] & 0xf8) | (mini[2] >> 5);
|
||||
mincolor[1] = (mini[1] & 0xfc) | (mini[1] >> 6);
|
||||
|
||||
maxcolor[2] = (maxi[2] & 0xf8) | (maxi[2] >> 5);
|
||||
maxcolor[1] = (maxi[1] & 0xfc) | (maxi[1] >> 6);
|
||||
}
|
||||
|
||||
static void
|
||||
select_diagonal_YCoCg (const guchar *block,
|
||||
guchar *mincolor,
|
||||
guchar *maxcolor)
|
||||
{
|
||||
guchar mid0, mid1, side, mask, b0, b1, c0, c1;
|
||||
gint i;
|
||||
|
||||
mid0 = ((gint) mincolor[2] + maxcolor[2] + 1) >> 1;
|
||||
mid1 = ((gint) mincolor[1] + maxcolor[1] + 1) >> 1;
|
||||
|
||||
side = 0;
|
||||
for (i = 0; i < 16; ++i)
|
||||
{
|
||||
b0 = block[i * 4 + 2] >= mid0;
|
||||
b1 = block[i * 4 + 1] >= mid1;
|
||||
side += (b0 ^ b1);
|
||||
}
|
||||
|
||||
mask = -(side > 8);
|
||||
mask &= -(mincolor[2] != maxcolor[2]);
|
||||
|
||||
c0 = mincolor[1];
|
||||
c1 = maxcolor[1];
|
||||
|
||||
c0 ^= c1;
|
||||
c1 ^= c0 & mask;
|
||||
c0 ^= c1;
|
||||
|
||||
mincolor[1] = c0;
|
||||
maxcolor[1] = c1;
|
||||
}
|
||||
|
||||
void
|
||||
encode_YCoCg_block (guchar *dst,
|
||||
guchar *block)
|
||||
{
|
||||
guchar colors[4][3], *maxcolor, *mincolor;
|
||||
guint mask;
|
||||
gint c0, c1, d0, d1, d2, d3;
|
||||
gint b0, b1, b2, b3, b4;
|
||||
gint x0, x1, x2;
|
||||
gint i, idx;
|
||||
|
||||
maxcolor = &colors[0][0];
|
||||
mincolor = &colors[1][0];
|
||||
|
||||
get_min_max_YCoCg (block, mincolor, maxcolor);
|
||||
scale_YCoCg (block, mincolor, maxcolor);
|
||||
inset_bbox_YCoCg (mincolor, maxcolor);
|
||||
select_diagonal_YCoCg (block, mincolor, maxcolor);
|
||||
|
||||
colors[2][0] = (2 * maxcolor[0] + mincolor[0]) / 3;
|
||||
colors[2][1] = (2 * maxcolor[1] + mincolor[1]) / 3;
|
||||
colors[2][2] = (2 * maxcolor[2] + mincolor[2]) / 3;
|
||||
|
||||
colors[3][0] = (2 * mincolor[0] + maxcolor[0]) / 3;
|
||||
colors[3][1] = (2 * mincolor[1] + maxcolor[1]) / 3;
|
||||
colors[3][2] = (2 * mincolor[2] + maxcolor[2]) / 3;
|
||||
|
||||
mask = 0;
|
||||
|
||||
for (i = 0; i < 16; ++i)
|
||||
{
|
||||
c0 = block[4 * i + 2];
|
||||
c1 = block[4 * i + 1];
|
||||
|
||||
d0 = abs (colors[0][2] - c0) + abs (colors[0][1] - c1);
|
||||
d1 = abs (colors[1][2] - c0) + abs (colors[1][1] - c1);
|
||||
d2 = abs (colors[2][2] - c0) + abs (colors[2][1] - c1);
|
||||
d3 = abs (colors[3][2] - c0) + abs (colors[3][1] - c1);
|
||||
|
||||
b0 = d0 > d3;
|
||||
b1 = d1 > d2;
|
||||
b2 = d0 > d2;
|
||||
b3 = d1 > d3;
|
||||
b4 = d2 > d3;
|
||||
|
||||
x0 = b1 & b2;
|
||||
x1 = b0 & b3;
|
||||
x2 = b0 & b4;
|
||||
|
||||
idx = (x2 | ((x0 | x1) << 1));
|
||||
|
||||
mask |= idx << (2 * i);
|
||||
}
|
||||
|
||||
PUTL16 (dst + 0, (mul8bit (maxcolor[2], 31) << 11) |
|
||||
(mul8bit (maxcolor[1], 63) << 5) |
|
||||
(mul8bit (maxcolor[0], 31) ));
|
||||
PUTL16 (dst + 2, (mul8bit (mincolor[2], 31) << 11) |
|
||||
(mul8bit (mincolor[1], 63) << 5) |
|
||||
(mul8bit (mincolor[0], 31) ));
|
||||
PUTL32 (dst + 4, mask);
|
||||
}
|
||||
|
@ -21,11 +21,26 @@
|
||||
#ifndef __MISC_H__
|
||||
#define __MISC_H__
|
||||
|
||||
void decode_ycocg_image (PikaDrawable *drawable,
|
||||
gboolean shadow);
|
||||
void decode_ycocg_scaled_image (PikaDrawable *drawable,
|
||||
gboolean shadow);
|
||||
void decode_alpha_exp_image (PikaDrawable *drawable,
|
||||
gboolean shadow);
|
||||
|
||||
void decode_ycocg (PikaDrawable *drawable);
|
||||
|
||||
void decode_ycocg_scaled (PikaDrawable *drawable);
|
||||
|
||||
void decode_alpha_exponent (PikaDrawable *drawable);
|
||||
|
||||
void encode_ycocg (guchar *dst,
|
||||
gint r,
|
||||
gint g,
|
||||
gint b);
|
||||
|
||||
void encode_alpha_exponent (guchar *dst,
|
||||
gint r,
|
||||
gint g,
|
||||
gint b,
|
||||
gint a);
|
||||
|
||||
void encode_YCoCg_block (guchar *dst,
|
||||
guchar *block);
|
||||
|
||||
|
||||
#endif /* __MISC_H__ */
|
||||
|
Reference in New Issue
Block a user