mirror of https://github.com/GNOME/gimp.git
Consolidate YCoCg/AlphaExp code, always decode
Moves most of the code relating to YCoCg and Alpha Exponent into misc.c/h, in the interest of making the rest of the codebase cleaner. Removes the decode option from the import menu, as encoded files are always decoded now (there used to be a menu button for doing this after import, but with it gone there's no reason ever to not decode). Finally, the remaining functions in color.c were only ever called once, so these were extracted and inlined, and the empty file deleted.
This commit is contained in:
parent
30922cc266
commit
a5d1d96a38
|
@ -1,62 +0,0 @@
|
|||
/*
|
||||
* DDS GIMP plugin
|
||||
*
|
||||
* 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 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include <libgimp/gimp.h>
|
||||
|
||||
#include "color.h"
|
||||
|
||||
|
||||
gfloat
|
||||
linear_to_sRGB (gfloat c)
|
||||
{
|
||||
gfloat v = (gfloat) c;
|
||||
|
||||
if (v < 0.0f)
|
||||
v = 0.0f;
|
||||
else if (v > 1.0f)
|
||||
v = 1.0f;
|
||||
else if (v <= 0.0031308f)
|
||||
v = 12.92f * v;
|
||||
else
|
||||
v = 1.055f * powf (v, 0.41666f) - 0.055f;
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
gfloat
|
||||
sRGB_to_linear (gfloat c)
|
||||
{
|
||||
gfloat v = (gfloat) c;
|
||||
|
||||
if (v < 0.0f)
|
||||
v = 0.0f;
|
||||
else if (v > 1.0f)
|
||||
v = 1.0f;
|
||||
else if (v <= 0.04045f)
|
||||
v /= 12.92f;
|
||||
else
|
||||
v = powf ((v + 0.055f) / 1.055f, 2.4f);
|
||||
|
||||
return v;
|
||||
}
|
|
@ -1,112 +0,0 @@
|
|||
/*
|
||||
* DDS GIMP plugin
|
||||
*
|
||||
* 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 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __COLOR_H__
|
||||
#define __COLOR_H__
|
||||
|
||||
|
||||
#include "imath.h"
|
||||
|
||||
|
||||
/* sRGB encoding & decoding */
|
||||
gfloat linear_to_sRGB (gfloat c);
|
||||
gfloat sRGB_to_linear (gfloat c);
|
||||
|
||||
|
||||
/* YCoCg encoding */
|
||||
static inline void
|
||||
RGB_to_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));
|
||||
}
|
||||
|
||||
|
||||
/* Other color conversions */
|
||||
static inline gint
|
||||
rgb_to_luminance (gint r,
|
||||
gint g,
|
||||
gint b)
|
||||
{
|
||||
/* ITU-R BT.709 luma coefficients, scaled by 256 */
|
||||
return ((r * 54 + g * 182 + b * 20) + 128) >> 8;
|
||||
}
|
||||
|
||||
static inline gushort
|
||||
pack_r5g6b5 (gint r,
|
||||
gint g,
|
||||
gint b)
|
||||
{
|
||||
return (mul8bit (r, 31) << 11) |
|
||||
(mul8bit (g, 63) << 5) |
|
||||
(mul8bit (b, 31) );
|
||||
}
|
||||
|
||||
static inline gushort
|
||||
pack_rgba4 (gint r,
|
||||
gint g,
|
||||
gint b,
|
||||
gint a)
|
||||
{
|
||||
return (mul8bit (a, 15) << 12) |
|
||||
(mul8bit (r, 15) << 8) |
|
||||
(mul8bit (g, 15) << 4) |
|
||||
(mul8bit (b, 15) );
|
||||
}
|
||||
|
||||
static inline gushort
|
||||
pack_rgb5a1 (gint r,
|
||||
gint g,
|
||||
gint b,
|
||||
gint a)
|
||||
{
|
||||
return (((a >> 7) & 0x01) << 15) |
|
||||
(mul8bit (r, 31) << 10) |
|
||||
(mul8bit (g, 31) << 5) |
|
||||
(mul8bit (b, 31) );
|
||||
}
|
||||
|
||||
static inline guchar
|
||||
pack_r3g3b2 (gint r,
|
||||
gint g,
|
||||
gint b)
|
||||
{
|
||||
return (mul8bit (r, 7) << 5) |
|
||||
(mul8bit (g, 7) << 2) |
|
||||
(mul8bit (b, 3) );
|
||||
}
|
||||
|
||||
static inline guint
|
||||
pack_rgb10a2 (gint r, gint g, gint b, gint a)
|
||||
{
|
||||
return ((guint) ((a >> 6) & 0x003) << 30) |
|
||||
((guint) ((b << 2) & 0x3ff) << 20) |
|
||||
((guint) ((g << 2) & 0x3ff) << 10) |
|
||||
((guint) ((r << 2) & 0x3ff) );
|
||||
}
|
||||
|
||||
|
||||
#endif /* __COLOR_H__ */
|
|
@ -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 GimpValueArray * dds_save (GimpProcedure *procedure,
|
|||
GimpMetadata *metadata,
|
||||
GimpProcedureConfig *config,
|
||||
gpointer run_data);
|
||||
#if 0
|
||||
static GimpValueArray * dds_decode (GimpProcedure *procedure,
|
||||
GimpRunMode run_mode,
|
||||
GimpImage *image,
|
||||
gint n_drawables,
|
||||
GimpDrawable **drawables,
|
||||
GimpProcedureConfig *config,
|
||||
gpointer run_data);
|
||||
#endif
|
||||
|
||||
|
||||
G_DEFINE_TYPE (Dds, dds, GIMP_TYPE_PLUG_IN)
|
||||
|
@ -125,11 +112,6 @@ dds_query_procedures (GimpPlugIn *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;
|
||||
}
|
||||
|
@ -183,12 +165,6 @@ dds_create_procedure (GimpPlugIn *plug_in,
|
|||
"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"),
|
||||
TRUE,
|
||||
G_PARAM_READWRITE);
|
||||
}
|
||||
else if (! strcmp (name, SAVE_PROC))
|
||||
{
|
||||
|
@ -358,78 +334,6 @@ dds_create_procedure (GimpPlugIn *plug_in,
|
|||
0.0, 1.0, 0.5,
|
||||
G_PARAM_READWRITE);
|
||||
}
|
||||
#if 0
|
||||
else if (! strcmp (name, DECODE_YCOCG_PROC))
|
||||
{
|
||||
procedure = gimp_image_procedure_new (plug_in, name,
|
||||
GIMP_PDB_PROC_TYPE_PLUGIN,
|
||||
dds_decode, NULL, NULL);
|
||||
|
||||
gimp_procedure_set_image_types (procedure, "RGBA");
|
||||
gimp_procedure_set_sensitivity_mask (procedure,
|
||||
GIMP_PROCEDURE_SENSITIVE_DRAWABLE);
|
||||
|
||||
gimp_procedure_set_menu_label (procedure, _("Decode YCoCg"));
|
||||
/* gimp_procedure_add_menu_path (procedure, "<Image>/Filters/Colors"); */
|
||||
|
||||
gimp_procedure_set_documentation (procedure,
|
||||
_("Converts YCoCg encoded pixels to RGB"),
|
||||
_("Converts YCoCg encoded pixels to RGB"),
|
||||
name);
|
||||
gimp_procedure_set_attribution (procedure,
|
||||
"Shawn Kirst",
|
||||
"Shawn Kirst",
|
||||
"2008");
|
||||
}
|
||||
else if (! strcmp (name, DECODE_YCOCG_SCALED_PROC))
|
||||
{
|
||||
procedure = gimp_image_procedure_new (plug_in, name,
|
||||
GIMP_PDB_PROC_TYPE_PLUGIN,
|
||||
dds_decode, NULL, NULL);
|
||||
|
||||
gimp_procedure_set_image_types (procedure, "RGBA");
|
||||
gimp_procedure_set_sensitivity_mask (procedure,
|
||||
GIMP_PROCEDURE_SENSITIVE_DRAWABLE);
|
||||
|
||||
gimp_procedure_set_menu_label (procedure, _("Decode YCoCg (scaled)"));
|
||||
/* gimp_procedure_add_menu_path (procedure, "<Image>/Filters/Colors"); */
|
||||
|
||||
gimp_procedure_set_documentation (procedure,
|
||||
_("Converts YCoCg (scaled) encoded "
|
||||
"pixels to RGB"),
|
||||
_("Converts YCoCg (scaled) encoded "
|
||||
"pixels to RGB"),
|
||||
name);
|
||||
gimp_procedure_set_attribution (procedure,
|
||||
"Shawn Kirst",
|
||||
"Shawn Kirst",
|
||||
"2008");
|
||||
}
|
||||
else if (! strcmp (name, DECODE_ALPHA_EXP_PROC))
|
||||
{
|
||||
procedure = gimp_image_procedure_new (plug_in, name,
|
||||
GIMP_PDB_PROC_TYPE_PLUGIN,
|
||||
dds_decode, NULL, NULL);
|
||||
|
||||
gimp_procedure_set_image_types (procedure, "RGBA");
|
||||
gimp_procedure_set_sensitivity_mask (procedure,
|
||||
GIMP_PROCEDURE_SENSITIVE_DRAWABLE);
|
||||
|
||||
gimp_procedure_set_menu_label (procedure, _("Decode Alpha exponent"));
|
||||
/* gimp_procedure_add_menu_path (procedure, "<Image>/Filters/Colors"); */
|
||||
|
||||
gimp_procedure_set_documentation (procedure,
|
||||
_("Converts alpha exponent encoded "
|
||||
"pixels to RGB",
|
||||
_("Converts alpha exponent encoded "
|
||||
"pixels to RGB"),
|
||||
name);
|
||||
gimp_procedure_set_attribution (procedure,
|
||||
"Shawn Kirst",
|
||||
"Shawn Kirst",
|
||||
"2008");
|
||||
}
|
||||
#endif
|
||||
|
||||
return procedure;
|
||||
}
|
||||
|
@ -535,53 +439,3 @@ dds_save (GimpProcedure *procedure,
|
|||
|
||||
return gimp_procedure_new_return_values (procedure, status, error);
|
||||
}
|
||||
|
||||
#if 0
|
||||
static GimpValueArray *
|
||||
dds_decode (GimpProcedure *procedure,
|
||||
GimpRunMode run_mode,
|
||||
GimpImage *image,
|
||||
gint n_drawables,
|
||||
GimpDrawable **drawables,
|
||||
GimpProcedureConfig *config,
|
||||
gpointer run_data)
|
||||
{
|
||||
const gchar *name = gimp_procedure_get_name (procedure);
|
||||
GimpDrawable *drawable,
|
||||
|
||||
if (n_drawables != 1)
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
||||
g_set_error (&error, GIMP_PLUG_IN_ERROR, 0,
|
||||
_("Procedure '%s' only works with one drawable."),
|
||||
name);
|
||||
|
||||
return gimp_procedure_new_return_values (procedure,
|
||||
GIMP_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 != GIMP_RUN_NONINTERACTIVE)
|
||||
gimp_displays_flush ();
|
||||
|
||||
return gimp_procedure_new_return_values (procedure, GIMP_PDB_SUCCESS, NULL);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -65,19 +65,19 @@ typedef struct
|
|||
} dds_load_info_t;
|
||||
|
||||
|
||||
static gboolean read_header (dds_header_t *hdr,
|
||||
FILE *fp);
|
||||
static gboolean read_header_dx10 (dds_header_dx10_t *hdr,
|
||||
FILE *fp);
|
||||
static gboolean validate_header (dds_header_t *hdr,
|
||||
GError **error);
|
||||
static gboolean setup_dxgi_format (dds_header_t *hdr,
|
||||
const dds_header_dx10_t *dx10hdr,
|
||||
dds_load_info_t *load_info,
|
||||
GError **error);
|
||||
static gboolean load_layer (FILE *fp,
|
||||
const dds_header_t *hdr,
|
||||
const dds_header_dx10_t *dx10hdr,
|
||||
static gboolean read_header (dds_header_t *hdr,
|
||||
FILE *fp);
|
||||
static gboolean read_header_dx10 (dds_header_dx10_t *hdr,
|
||||
FILE *fp);
|
||||
static gboolean validate_header (dds_header_t *hdr,
|
||||
GError **error);
|
||||
static gboolean setup_dxgi_format (dds_header_t *hdr,
|
||||
const dds_header_dx10_t *dx10hdr,
|
||||
dds_load_info_t *load_info,
|
||||
GError **error);
|
||||
static gboolean load_layer (FILE *fp,
|
||||
const dds_header_t *hdr,
|
||||
const dds_header_dx10_t *dx10hdr,
|
||||
dds_load_info_t *load_info,
|
||||
GimpImage *image,
|
||||
guint level,
|
||||
|
@ -85,7 +85,6 @@ static gboolean load_layer (FILE *fp,
|
|||
guint *layer_index,
|
||||
guchar *pixels,
|
||||
guchar *buf,
|
||||
gboolean decode_images,
|
||||
GError **error);
|
||||
static gboolean load_mipmaps (FILE *fp,
|
||||
const dds_header_t *hdr,
|
||||
|
@ -97,24 +96,22 @@ static gboolean load_mipmaps (FILE *fp,
|
|||
guchar *pixels,
|
||||
guchar *buf,
|
||||
gboolean read_mipmaps,
|
||||
gboolean decode_images,
|
||||
GError **error);
|
||||
static gboolean load_face (FILE *fp,
|
||||
const dds_header_t *hdr,
|
||||
const dds_header_dx10_t *dx10hdr,
|
||||
dds_load_info_t *load_info,
|
||||
GimpImage *image,
|
||||
gchar *prefix,
|
||||
guint *layer_index,
|
||||
guchar *pixels,
|
||||
guchar *buf,
|
||||
gboolean read_mipmaps,
|
||||
gboolean decode_images,
|
||||
GError **error);
|
||||
static guchar color_bits (guint mask);
|
||||
static guchar color_shift (guint mask);
|
||||
static gboolean load_dialog (GimpProcedure *procedure,
|
||||
GimpProcedureConfig *config);
|
||||
const dds_header_t *hdr,
|
||||
const dds_header_dx10_t *dx10hdr,
|
||||
dds_load_info_t *load_info,
|
||||
GimpImage *image,
|
||||
gchar *prefix,
|
||||
guint *layer_index,
|
||||
guchar *pixels,
|
||||
guchar *buf,
|
||||
gboolean read_mipmaps,
|
||||
GError **error);
|
||||
static guchar color_bits (guint mask);
|
||||
static guchar color_shift (guint mask);
|
||||
static gboolean load_dialog (GimpProcedure *procedure,
|
||||
GimpProcedureConfig *config);
|
||||
|
||||
|
||||
/* Read DDS file */
|
||||
|
@ -138,7 +135,6 @@ read_dds (GFile *file,
|
|||
GimpImageBaseType type;
|
||||
GimpPrecision precision;
|
||||
gboolean read_mipmaps;
|
||||
gboolean decode_images;
|
||||
gint i, j;
|
||||
guint computed_pitch_or_linsize;
|
||||
gboolean flip_import;
|
||||
|
@ -156,7 +152,6 @@ read_dds (GFile *file,
|
|||
"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");
|
||||
|
@ -629,7 +624,7 @@ read_dds (GFile *file,
|
|||
dx10hdr.arraySize <= 1) /* Standard image texture with mipmaps */
|
||||
{
|
||||
if (! load_layer (fp, &hdr, &dx10hdr, &load_info, image, 0, "", &layer_index,
|
||||
pixels, buf, decode_images, error))
|
||||
pixels, buf, error))
|
||||
{
|
||||
fclose (fp);
|
||||
gimp_image_delete (image);
|
||||
|
@ -637,7 +632,7 @@ read_dds (GFile *file,
|
|||
}
|
||||
|
||||
if (! load_mipmaps (fp, &hdr, &dx10hdr, &load_info, image, "", &layer_index,
|
||||
pixels, buf, read_mipmaps, decode_images, error))
|
||||
pixels, buf, read_mipmaps, error))
|
||||
{
|
||||
fclose (fp);
|
||||
gimp_image_delete (image);
|
||||
|
@ -648,7 +643,7 @@ read_dds (GFile *file,
|
|||
{
|
||||
if ((hdr.caps.caps2 & DDSCAPS2_CUBEMAP_POSITIVEX) &&
|
||||
! load_face (fp, &hdr, &dx10hdr, &load_info, image, "(positive x)",
|
||||
&layer_index, pixels, buf, read_mipmaps, decode_images, error))
|
||||
&layer_index, pixels, buf, read_mipmaps, error))
|
||||
{
|
||||
fclose (fp);
|
||||
gimp_image_delete (image);
|
||||
|
@ -657,7 +652,7 @@ read_dds (GFile *file,
|
|||
|
||||
if ((hdr.caps.caps2 & DDSCAPS2_CUBEMAP_NEGATIVEX) &&
|
||||
! load_face (fp, &hdr, &dx10hdr, &load_info, image, "(negative x)",
|
||||
&layer_index, pixels, buf, read_mipmaps, decode_images, error))
|
||||
&layer_index, pixels, buf, read_mipmaps, error))
|
||||
{
|
||||
fclose (fp);
|
||||
gimp_image_delete (image);
|
||||
|
@ -666,7 +661,7 @@ read_dds (GFile *file,
|
|||
|
||||
if ((hdr.caps.caps2 & DDSCAPS2_CUBEMAP_POSITIVEY) &&
|
||||
! load_face (fp, &hdr, &dx10hdr, &load_info, image, "(positive y)",
|
||||
&layer_index, pixels, buf, read_mipmaps, decode_images, error))
|
||||
&layer_index, pixels, buf, read_mipmaps, error))
|
||||
{
|
||||
fclose (fp);
|
||||
gimp_image_delete (image);
|
||||
|
@ -675,7 +670,7 @@ read_dds (GFile *file,
|
|||
|
||||
if ((hdr.caps.caps2 & DDSCAPS2_CUBEMAP_NEGATIVEY) &&
|
||||
! load_face (fp, &hdr, &dx10hdr, &load_info, image, "(negative y)",
|
||||
&layer_index, pixels, buf, read_mipmaps, decode_images, error))
|
||||
&layer_index, pixels, buf, read_mipmaps, error))
|
||||
{
|
||||
fclose (fp);
|
||||
gimp_image_delete (image);
|
||||
|
@ -684,7 +679,7 @@ read_dds (GFile *file,
|
|||
|
||||
if ((hdr.caps.caps2 & DDSCAPS2_CUBEMAP_POSITIVEZ) &&
|
||||
! load_face (fp, &hdr, &dx10hdr, &load_info, image, "(positive z)",
|
||||
&layer_index, pixels, buf, read_mipmaps, decode_images, error))
|
||||
&layer_index, pixels, buf, read_mipmaps, error))
|
||||
{
|
||||
fclose (fp);
|
||||
gimp_image_delete (image);
|
||||
|
@ -693,7 +688,7 @@ read_dds (GFile *file,
|
|||
|
||||
if ((hdr.caps.caps2 & DDSCAPS2_CUBEMAP_NEGATIVEZ) &&
|
||||
! load_face (fp, &hdr, &dx10hdr, &load_info, image, "(negative z)",
|
||||
&layer_index, pixels, buf, read_mipmaps, decode_images, error))
|
||||
&layer_index, pixels, buf, read_mipmaps, error))
|
||||
{
|
||||
fclose (fp);
|
||||
gimp_image_delete (image);
|
||||
|
@ -711,7 +706,7 @@ read_dds (GFile *file,
|
|||
plane = g_strdup_printf ("(z = %d)", i);
|
||||
|
||||
if (! load_layer (fp, &hdr, &dx10hdr, &load_info, image, 0, plane,
|
||||
&layer_index, pixels, buf, decode_images, error))
|
||||
&layer_index, pixels, buf, error))
|
||||
{
|
||||
g_free (plane);
|
||||
fclose (fp);
|
||||
|
@ -738,7 +733,7 @@ read_dds (GFile *file,
|
|||
plane = g_strdup_printf ("(z = %d)", i);
|
||||
|
||||
if (! load_layer (fp, &hdr, &dx10hdr, &load_info, image, level, plane,
|
||||
&layer_index, pixels, buf, decode_images, error))
|
||||
&layer_index, pixels, buf, error))
|
||||
{
|
||||
g_free (plane);
|
||||
fclose (fp);
|
||||
|
@ -761,7 +756,7 @@ read_dds (GFile *file,
|
|||
elem = g_strdup_printf ("(array element %d)", i);
|
||||
|
||||
if (! load_layer (fp, &hdr, &dx10hdr, &load_info, image, 0, elem, &layer_index,
|
||||
pixels, buf, decode_images, error))
|
||||
pixels, buf, error))
|
||||
{
|
||||
fclose (fp);
|
||||
gimp_image_delete (image);
|
||||
|
@ -769,7 +764,7 @@ read_dds (GFile *file,
|
|||
}
|
||||
|
||||
if (! load_mipmaps (fp, &hdr, &dx10hdr, &load_info, image, elem, &layer_index,
|
||||
pixels, buf, read_mipmaps, decode_images, error))
|
||||
pixels, buf, read_mipmaps, error))
|
||||
{
|
||||
fclose (fp);
|
||||
gimp_image_delete (image);
|
||||
|
@ -1309,7 +1304,6 @@ load_layer (FILE *fp,
|
|||
guint *layer_index,
|
||||
guchar *pixels,
|
||||
guchar *buf,
|
||||
gboolean decode_images,
|
||||
GError **error)
|
||||
{
|
||||
GeglBuffer *buffer;
|
||||
|
@ -2025,21 +2019,20 @@ load_layer (FILE *fp,
|
|||
|
||||
g_object_unref (buffer);
|
||||
|
||||
/* gimp dds specific. decode encoded images */
|
||||
if (decode_images &&
|
||||
hdr->reserved.gimp_dds_special.magic1 == FOURCC ('G','I','M','P') &&
|
||||
/* Decode files with GIMP-specific encodings */
|
||||
if (hdr->reserved.gimp_dds_special.magic1 == FOURCC ('G','I','M','P') &&
|
||||
hdr->reserved.gimp_dds_special.magic2 == FOURCC ('-','D','D','S'))
|
||||
{
|
||||
switch (hdr->reserved.gimp_dds_special.extra_fourcc)
|
||||
{
|
||||
case FOURCC ('A','E','X','P'):
|
||||
decode_alpha_exp_image (GIMP_DRAWABLE (layer), FALSE);
|
||||
decode_alpha_exponent (GIMP_DRAWABLE (layer));
|
||||
break;
|
||||
case FOURCC ('Y','C','G','1'):
|
||||
decode_ycocg_image (GIMP_DRAWABLE (layer), FALSE);
|
||||
decode_ycocg (GIMP_DRAWABLE (layer));
|
||||
break;
|
||||
case FOURCC ('Y','C','G','2'):
|
||||
decode_ycocg_scaled_image (GIMP_DRAWABLE (layer), FALSE);
|
||||
decode_ycocg_scaled (GIMP_DRAWABLE (layer));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -2060,7 +2053,6 @@ load_mipmaps (FILE *fp,
|
|||
guchar *pixels,
|
||||
guchar *buf,
|
||||
gboolean read_mipmaps,
|
||||
gboolean decode_images,
|
||||
GError **error)
|
||||
{
|
||||
guint level;
|
||||
|
@ -2072,7 +2064,7 @@ load_mipmaps (FILE *fp,
|
|||
for (level = 1; level < hdr->num_mipmaps; ++level)
|
||||
{
|
||||
if (! load_layer (fp, hdr, dx10hdr, load_info, image, level, prefix, layer_index,
|
||||
pixels, buf, decode_images, error))
|
||||
pixels, buf, error))
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
@ -2091,15 +2083,14 @@ load_face (FILE *fp,
|
|||
guchar *pixels,
|
||||
guchar *buf,
|
||||
gboolean read_mipmaps,
|
||||
gboolean decode_images,
|
||||
GError **error)
|
||||
{
|
||||
if (! load_layer (fp, hdr, dx10hdr, load_info, image, 0, prefix,
|
||||
layer_index, pixels, buf, decode_images, error))
|
||||
layer_index, pixels, buf, error))
|
||||
return FALSE;
|
||||
|
||||
return load_mipmaps (fp, hdr, dx10hdr, load_info, image, prefix, layer_index,
|
||||
pixels, buf, read_mipmaps, decode_images, error);
|
||||
pixels, buf, read_mipmaps, error);
|
||||
}
|
||||
|
||||
static guchar
|
||||
|
@ -2124,7 +2115,7 @@ color_shift (guint mask)
|
|||
if (! mask)
|
||||
return 0;
|
||||
|
||||
while (!((mask >> i) & 1))
|
||||
while (! ((mask >> i) & 1))
|
||||
++i;
|
||||
|
||||
return i;
|
||||
|
@ -2147,7 +2138,6 @@ load_dialog (GimpProcedure *procedure,
|
|||
"load-mipmaps",
|
||||
"flip-image",
|
||||
"bc1-use-transparency",
|
||||
"decode-images",
|
||||
NULL);
|
||||
gtk_box_set_spacing (GTK_BOX (vbox), 8);
|
||||
gtk_container_set_border_width (GTK_CONTAINER (vbox), 8);
|
||||
|
|
|
@ -35,13 +35,13 @@
|
|||
|
||||
#include <libgimp/stdplugins-intl.h>
|
||||
|
||||
#include "color.h"
|
||||
#include "dds.h"
|
||||
#include "ddswrite.h"
|
||||
#include "dxt.h"
|
||||
#include "endian_rw.h"
|
||||
#include "imath.h"
|
||||
#include "mipmap.h"
|
||||
#include "misc.h"
|
||||
|
||||
|
||||
static gboolean write_image (FILE *fp,
|
||||
|
@ -244,7 +244,7 @@ check_cubemap (GimpImage *image)
|
|||
(gimp_drawable_get_height (drawable) != h))
|
||||
continue;
|
||||
|
||||
layer_name = (char *) gimp_item_get_name (GIMP_ITEM (drawable));
|
||||
layer_name = (gchar *) gimp_item_get_name (GIMP_ITEM (drawable));
|
||||
for (j = 0; j < 6; ++j)
|
||||
{
|
||||
for (k = 0; k < 4; ++k)
|
||||
|
@ -608,45 +608,6 @@ swap_rb (guchar *pixels,
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
alpha_exp (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));
|
||||
}
|
||||
|
||||
static void
|
||||
convert_pixels (guchar *dst,
|
||||
guchar *src,
|
||||
|
@ -729,36 +690,56 @@ convert_pixels (guchar *dst,
|
|||
dst[4 * i + 3] = a;
|
||||
break;
|
||||
case DDS_FORMAT_R5G6B5:
|
||||
PUTL16 (&dst[2 * i], pack_r5g6b5 (r, g, b));
|
||||
PUTL16 (&dst[2 * i],
|
||||
(mul8bit (r, 31) << 11) |
|
||||
(mul8bit (g, 63) << 5) |
|
||||
(mul8bit (b, 31) ));
|
||||
break;
|
||||
case DDS_FORMAT_RGBA4:
|
||||
PUTL16 (&dst[2 * i], pack_rgba4 (r, g, b, a));
|
||||
PUTL16 (&dst[2 * i],
|
||||
(mul8bit (a, 15) << 12) |
|
||||
(mul8bit (r, 15) << 8) |
|
||||
(mul8bit (g, 15) << 4) |
|
||||
(mul8bit (b, 15) ));
|
||||
break;
|
||||
case DDS_FORMAT_RGB5A1:
|
||||
PUTL16 (&dst[2 * i], pack_rgb5a1 (r, g, b, a));
|
||||
PUTL16 (&dst[2 * i],
|
||||
(((a >> 7) & 0x01) << 15) |
|
||||
(mul8bit (r, 31) << 10) |
|
||||
(mul8bit (g, 31) << 5) |
|
||||
(mul8bit (b, 31) ));
|
||||
break;
|
||||
case DDS_FORMAT_RGB10A2:
|
||||
PUTL32 (&dst[4 * i], pack_rgb10a2 (r, g, b, a));
|
||||
PUTL32 (&dst[4 * i],
|
||||
((guint) ((a >> 6) & 0x003) << 30) |
|
||||
((guint) ((b << 2) & 0x3ff) << 20) |
|
||||
((guint) ((g << 2) & 0x3ff) << 10) |
|
||||
((guint) ((r << 2) & 0x3ff) ));
|
||||
break;
|
||||
case DDS_FORMAT_R3G3B2:
|
||||
dst[i] = pack_r3g3b2 (r, g, b);
|
||||
dst[i] =
|
||||
(mul8bit (r, 7) << 5) |
|
||||
(mul8bit (g, 7) << 2) |
|
||||
(mul8bit (b, 3) );
|
||||
break;
|
||||
case DDS_FORMAT_A8:
|
||||
dst[i] = a;
|
||||
break;
|
||||
case DDS_FORMAT_L8:
|
||||
dst[i] = rgb_to_luminance (r, g, b);
|
||||
dst[i] =
|
||||
((r * 54 + g * 182 + b * 20) + 128) >> 8;
|
||||
break;
|
||||
case DDS_FORMAT_L8A8:
|
||||
dst[2 * i + 0] = rgb_to_luminance (r, g, b);
|
||||
dst[2 * i + 0] =
|
||||
((r * 54 + g * 182 + b * 20) + 128) >> 8;
|
||||
dst[2 * i + 1] = a;
|
||||
break;
|
||||
case DDS_FORMAT_YCOCG:
|
||||
dst[4 * i] = a;
|
||||
RGB_to_YCoCg (&dst[4 * i], r, g, b);
|
||||
encode_ycocg (&dst[4 * i], r, g, b);
|
||||
break;
|
||||
case DDS_FORMAT_AEXP:
|
||||
alpha_exp (&dst[4 * i], r, g, b, a);
|
||||
encode_alpha_exponent (&dst[4 * i], r, g, b, a);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
|
@ -34,11 +34,14 @@
|
|||
#include <math.h>
|
||||
#include <glib.h>
|
||||
|
||||
#include <libgimp/gimp.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,
|
||||
|
|
|
@ -2,7 +2,6 @@ plugin_name = 'file-dds'
|
|||
|
||||
plugin_sources = [
|
||||
'dds.c',
|
||||
'color.c',
|
||||
'ddsread.c',
|
||||
'ddswrite.c',
|
||||
'dxt.c',
|
||||
|
|
|
@ -36,7 +36,6 @@
|
|||
#include "dds.h"
|
||||
#include "mipmap.h"
|
||||
#include "imath.h"
|
||||
#include "color.h"
|
||||
|
||||
|
||||
typedef gfloat (*filterfunc_t) (gfloat);
|
||||
|
@ -217,6 +216,23 @@ wrap_clamp (gint x,
|
|||
* Gamma-correction
|
||||
*/
|
||||
|
||||
static gfloat
|
||||
linear_to_sRGB (gfloat c)
|
||||
{
|
||||
gfloat v = (gfloat) c;
|
||||
|
||||
if (v < 0.0f)
|
||||
v = 0.0f;
|
||||
else if (v > 1.0f)
|
||||
v = 1.0f;
|
||||
else if (v <= 0.0031308f)
|
||||
v = 12.92f * v;
|
||||
else
|
||||
v = 1.055f * powf (v, 0.41666f) - 0.055f;
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
static gfloat
|
||||
linear_to_gamma (gint gc,
|
||||
gfloat v,
|
||||
|
@ -236,6 +252,24 @@ linear_to_gamma (gint gc,
|
|||
return v;
|
||||
}
|
||||
|
||||
|
||||
static gfloat
|
||||
sRGB_to_linear (gfloat c)
|
||||
{
|
||||
gfloat v = (gfloat) c;
|
||||
|
||||
if (v < 0.0f)
|
||||
v = 0.0f;
|
||||
else if (v > 1.0f)
|
||||
v = 1.0f;
|
||||
else if (v <= 0.04045f)
|
||||
v /= 12.92f;
|
||||
else
|
||||
v = powf ((v + 0.055f) / 1.055f, 2.4f);
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
static gfloat
|
||||
gamma_to_linear (gint gc,
|
||||
gfloat v,
|
||||
|
|
|
@ -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 <libgimp/gimp.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 (GimpDrawable *drawable,
|
||||
gboolean shadow)
|
||||
decode_ycocg (GimpDrawable *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 = gimp_drawable_get_buffer (drawable);
|
||||
|
||||
if (shadow)
|
||||
{
|
||||
sbuffer = gimp_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 (GimpDrawable *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);
|
||||
|
||||
gimp_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)
|
||||
gimp_progress_update ((float)i / (float)num_pixels);
|
||||
gimp_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);
|
||||
|
||||
gimp_progress_update (1.0);
|
||||
|
||||
gegl_buffer_flush (buffer);
|
||||
|
||||
if (shadow)
|
||||
gimp_drawable_merge_shadow (drawable, TRUE);
|
||||
|
||||
gimp_drawable_update (drawable, 0, 0, w, h);
|
||||
|
||||
g_free (data);
|
||||
|
@ -110,27 +104,19 @@ decode_ycocg_image (GimpDrawable *drawable,
|
|||
}
|
||||
|
||||
void
|
||||
decode_ycocg_scaled_image (GimpDrawable *drawable,
|
||||
gboolean shadow)
|
||||
decode_ycocg_scaled (GimpDrawable *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 = gimp_drawable_get_buffer (drawable);
|
||||
|
||||
if (shadow)
|
||||
{
|
||||
sbuffer = gimp_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 (GimpDrawable *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);
|
||||
|
||||
gimp_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 (GimpDrawable *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)
|
||||
gimp_progress_update ((float)i / (float)num_pixels);
|
||||
gimp_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);
|
||||
|
||||
gimp_progress_update (1.0);
|
||||
|
||||
gegl_buffer_flush (buffer);
|
||||
|
||||
if (shadow)
|
||||
gimp_drawable_merge_shadow (drawable, TRUE);
|
||||
|
||||
gimp_drawable_update (drawable, 0, 0, w, h);
|
||||
|
||||
g_free (data);
|
||||
|
@ -190,25 +173,17 @@ decode_ycocg_scaled_image (GimpDrawable *drawable,
|
|||
}
|
||||
|
||||
void
|
||||
decode_alpha_exp_image (GimpDrawable *drawable,
|
||||
gboolean shadow)
|
||||
decode_alpha_exponent (GimpDrawable *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 = gimp_drawable_get_buffer (drawable);
|
||||
|
||||
if (shadow)
|
||||
{
|
||||
sbuffer = gimp_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 (GimpDrawable *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);
|
||||
|
||||
gimp_progress_init ("Decoding Alpha-exponent pixels...");
|
||||
|
@ -240,22 +215,268 @@ decode_alpha_exp_image (GimpDrawable *drawable,
|
|||
data[4 * i + 3] = A;
|
||||
|
||||
if ((i & 0x7fff) == 0)
|
||||
gimp_progress_update ((float)i / (float)num_pixels);
|
||||
gimp_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);
|
||||
|
||||
gimp_progress_update (1.0);
|
||||
|
||||
gegl_buffer_flush (buffer);
|
||||
|
||||
if (shadow)
|
||||
gimp_drawable_merge_shadow (drawable, TRUE);
|
||||
|
||||
gimp_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 (GimpDrawable *drawable,
|
||||
gboolean shadow);
|
||||
void decode_ycocg_scaled_image (GimpDrawable *drawable,
|
||||
gboolean shadow);
|
||||
void decode_alpha_exp_image (GimpDrawable *drawable,
|
||||
gboolean shadow);
|
||||
|
||||
void decode_ycocg (GimpDrawable *drawable);
|
||||
|
||||
void decode_ycocg_scaled (GimpDrawable *drawable);
|
||||
|
||||
void decode_alpha_exponent (GimpDrawable *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__ */
|
||||
|
|
Loading…
Reference in New Issue