GrafX2 2.9.3227
The ultimate 256-color painting program
op_c.c File Reference
#include <assert.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <math.h>
#include "op_c.h"
#include "errors.h"
#include "colorred.h"
#include "global.h"
#include <limits.h>
#include "engine.h"
#include "windows.h"
+ Include dependency graph for op_c.c:

Macros

#define GRAFX2_QUANTIZE_CLUSTER_POPULATION_SPLIT
 

Functions

void RGB_to_HSL (int r, int g, int b, byte *hr, byte *sr, byte *lr)
 Convert RGB to HSL. More...
 
void HSL_to_RGB (byte h, byte s, byte l, byte *r, byte *g, byte *b)
 Convert HSL back to RGB Input and output are all in range 0..255. More...
 
long Perceptual_lightness (T_Components *color)
 Returns a value that is high when color is near white, and low when it's darker. More...
 
void OT_init (T_Occurrence_table *t)
 Initialize an occurrence table. More...
 
T_Occurrence_tableOT_new (int nbb_r, int nbb_g, int nbb_b)
 Allocate an occurrence table for given number of bits. More...
 
void OT_delete (T_Occurrence_table *t)
 Delete a table and free the memory. More...
 
int OT_get (T_Occurrence_table *t, byte r, byte g, byte b)
 Get number of occurrences for a given color. More...
 
void OT_inc (T_Occurrence_table *t, byte r, byte g, byte b)
 Add 1 to the count for a color. More...
 
void OT_count_occurrences (T_Occurrence_table *t, T_Bitmap24B image, int size)
 Count the use of each color in a 24bit picture and fill in the table. More...
 
int OT_count_colors (T_Occurrence_table *t)
 Count the total number of pixels in an occurrence table. More...
 
void Cluster_pack (T_Cluster *c, const T_Occurrence_table *const to)
 Pack a cluster, ie compute its {r,v,b}{min,max} values. More...
 
void Cluster_split (T_Cluster *c, T_Cluster *c1, T_Cluster *c2, int hue, const T_Occurrence_table *const to)
 Split a cluster on its longest axis. More...
 
void Cluster_compute_hue (T_Cluster *c, T_Occurrence_table *to)
 Compute the mean R, G, B (for palette generation) and H, L (for palette sorting) More...
 
void CT_set_trad (CT_Tree *colorTree, byte Rmin, byte Gmin, byte Bmin, byte Rmax, byte Gmax, byte Bmax, byte index, const T_Occurrence_table *to)
 
void CS_Init (T_Cluster_set *cs, T_Occurrence_table *to)
 Setup the first cluster before we start the operations This one covers the full palette range. More...
 
T_Cluster_setCS_New (int nbmax, T_Occurrence_table *to)
 Allocate a new cluster set. More...
 
void CS_Delete (T_Cluster_set *cs)
 Free a cluster set. More...
 
void CS_Get (T_Cluster_set *cs, T_Cluster **c)
 Pop a cluster from the cluster list. More...
 
int CS_Set (T_Cluster_set *cs, T_Cluster *c)
 Push a copy of a cluster in the list return -1 in case of error. More...
 
int CS_Generate (T_Cluster_set *cs, const T_Occurrence_table *const to, CT_Tree *colorTree)
 This is the main median cut algorithm and the function actually called to reduce the palette. More...
 
void CS_Compute_colors (T_Cluster_set *cs, T_Occurrence_table *to)
 Compute the color associated to each box in the list. More...
 
void CS_Sort_by_chrominance (T_Cluster_set *cs)
 Sort the clusters by chrominance value. More...
 
void CS_Sort_by_luminance (T_Cluster_set *cs)
 Sort the clusters by luminance value. More...
 
void CS_Generate_color_table_and_palette (T_Cluster_set *cs, CT_Tree *tc, T_Components *palette, T_Occurrence_table *to)
 Generates the palette from the clusters, then the conversion table to map (RGB) to a palette index. More...
 
void GS_Init (T_Gradient_set *ds, T_Cluster_set *cs)
 
T_Gradient_setGS_New (T_Cluster_set *cs)
 
void GS_Delete (T_Gradient_set *ds)
 
void GS_Generate (T_Gradient_set *ds, T_Cluster_set *cs)
 
CT_TreeOptimize_palette (T_Bitmap24B image, int size, T_Components *palette, int r, int g, int b)
 Compute best palette for given picture. More...
 
int Modified_value (int value, int modif)
 Change a value with proper ceiling and flooring. More...
 
void Convert_24b_bitmap_to_256_Floyd_Steinberg (T_Bitmap256 dest, T_Bitmap24B source, int width, int height, T_Components *palette, CT_Tree *tc)
 Convert a 24b image to 256 colors (with a given palette and conversion table). More...
 
void Convert_24b_bitmap_to_256_nearest_neighbor (T_Bitmap256 dest, T_Bitmap24B source, int width, int height, T_Components *palette, CT_Tree *tc)
 Converts from 24b to 256c without dithering, using given conversion table. More...
 
int Try_Convert_to_256_Without_Loss (T_Bitmap256 dest, T_Bitmap24B source, int width, int height, T_Components *palette)
 
int Convert_24b_bitmap_to_256 (T_Bitmap256 dest, T_Bitmap24B source, int width, int height, T_Components *palette)
 Converts a 24 bit picture to 256 color (color reduction) More...
 
void Set_palette_fake_24b (T_Palette palette)
 

Variables

static const byte precision_24b []
 

Macro Definition Documentation

◆ GRAFX2_QUANTIZE_CLUSTER_POPULATION_SPLIT

#define GRAFX2_QUANTIZE_CLUSTER_POPULATION_SPLIT

Function Documentation

◆ RGB_to_HSL()

void RGB_to_HSL ( int  r,
int  g,
int  b,
byte hr,
byte sr,
byte lr 
)

Convert RGB to HSL.

Both input and output are in the 0..255 range to use in the palette screen

Referenced by Button_Palette(), Cluster_compute_hue(), Compute_optimal_menu_colors(), Display_sliders(), Draw_all_palette_sliders(), and Set_HSL().

◆ HSL_to_RGB()

void HSL_to_RGB ( byte  h,
byte  s,
byte  l,
byte r,
byte g,
byte b 
)

Convert HSL back to RGB Input and output are all in range 0..255.

Referenced by Button_Palette(), and Set_HSL().

◆ Perceptual_lightness()

long Perceptual_lightness ( T_Components color)

Returns a value that is high when color is near white, and low when it's darker.

Used for sorting.

References T_Components::B, T_Components::G, and T_Components::R.

Referenced by Button_Palette().

◆ OT_init()

void OT_init ( T_Occurrence_table t)

◆ OT_new()

◆ OT_delete()

void OT_delete ( T_Occurrence_table t)

Delete a table and free the memory.

References NULL, and T_Occurrence_table::table.

Referenced by Optimize_palette().

◆ OT_get()

int OT_get ( T_Occurrence_table t,
byte  r,
byte  g,
byte  b 
)

Get number of occurrences for a given color.

References T_Occurrence_table::dec_b, T_Occurrence_table::dec_g, T_Occurrence_table::dec_r, and T_Occurrence_table::table.

Referenced by Cluster_compute_hue().

◆ OT_inc()

◆ OT_count_occurrences()

void OT_count_occurrences ( T_Occurrence_table t,
T_Bitmap24B  image,
int  size 
)

Count the use of each color in a 24bit picture and fill in the table.

References T_Components::B, T_Components::G, OT_inc(), and T_Components::R.

Referenced by Optimize_palette().

◆ OT_count_colors()

int OT_count_colors ( T_Occurrence_table t)

Count the total number of pixels in an occurrence table.

References T_Occurrence_table::rng_b, T_Occurrence_table::rng_g, T_Occurrence_table::rng_r, and T_Occurrence_table::table.

Referenced by CS_New().

◆ Cluster_pack()

◆ Cluster_split()

void Cluster_split ( T_Cluster c,
T_Cluster c1,
T_Cluster c2,
int  hue,
const T_Occurrence_table *const  to 
)

Split a cluster on its longest axis.

c = source cluster, c1, c2 = output after split the two output clusters have half population (and not half volume)

References T_Cluster::bmax, T_Cluster::Bmax, T_Cluster::bmin, T_Cluster::Bmin, T_Cluster::Gmin, T_Cluster::occurences, T_Cluster::rmax, T_Cluster::Rmax, T_Cluster::rmin, T_Cluster::Rmin, T_Cluster::vmax, T_Cluster::Vmax, and T_Cluster::vmin.

Referenced by CS_Generate().

◆ Cluster_compute_hue()

◆ CT_set_trad()

void CT_set_trad ( CT_Tree colorTree,
byte  Rmin,
byte  Gmin,
byte  Bmin,
byte  Rmax,
byte  Gmax,
byte  Bmax,
byte  index,
const T_Occurrence_table to 
)

◆ CS_Init()

◆ CS_New()

T_Cluster_set * CS_New ( int  nbmax,
T_Occurrence_table to 
)

Allocate a new cluster set.

References T_Cluster_set::clusters, CS_Init(), T_Cluster_set::nb_max, NULL, and OT_count_colors().

Referenced by Optimize_palette().

◆ CS_Delete()

void CS_Delete ( T_Cluster_set cs)

Free a cluster set.

References T_Cluster_set::clusters, T_Cluster::next, and NULL.

Referenced by Optimize_palette().

◆ CS_Get()

void CS_Get ( T_Cluster_set cs,
T_Cluster **  c 
)

Pop a cluster from the cluster list.

References T_Cluster_set::clusters, T_Cluster_set::nb, and T_Cluster::next.

Referenced by CS_Generate().

◆ CS_Set()

int CS_Set ( T_Cluster_set cs,
T_Cluster c 
)

Push a copy of a cluster in the list return -1 in case of error.

References T_Cluster_set::clusters, U_Cluster_Data::cut, T_Cluster::data, T_Cluster_set::nb, T_Cluster::next, NULL, S_Cluster_CutData::sqdiag, and S_Cluster_CutData::volume.

Referenced by CS_Generate().

◆ CS_Generate()

int CS_Generate ( T_Cluster_set cs,
const T_Occurrence_table *const  to,
CT_Tree colorTree 
)

This is the main median cut algorithm and the function actually called to reduce the palette.

We get the number of pixels for each collor in the occurrence table and generate the cluster set from it.

References T_Cluster::Bmax, T_Cluster::Bmin, Cluster_pack(), Cluster_split(), CS_Get(), CS_Set(), CT_set_trad(), U_Cluster_Data::cut, T_Cluster::data, T_Cluster::Gmin, T_Cluster_set::nb, T_Cluster_set::nb_max, T_Cluster::occurences, S_Cluster_CutData::plus_large, T_Cluster::Rmax, T_Cluster::Rmin, T_Cluster::Vmax, and S_Cluster_CutData::volume.

Referenced by Optimize_palette().

◆ CS_Compute_colors()

void CS_Compute_colors ( T_Cluster_set cs,
T_Occurrence_table to 
)

Compute the color associated to each box in the list.

References Cluster_compute_hue(), T_Cluster_set::clusters, T_Cluster::next, and NULL.

Referenced by Optimize_palette().

◆ CS_Sort_by_chrominance()

void CS_Sort_by_chrominance ( T_Cluster_set cs)

Sort the clusters by chrominance value.

References T_Cluster_set::clusters, T_Cluster::data, S_Cluster_PalData::h, T_Cluster::next, NULL, and U_Cluster_Data::pal.

Referenced by Optimize_palette().

◆ CS_Sort_by_luminance()

void CS_Sort_by_luminance ( T_Cluster_set cs)

Sort the clusters by luminance value.

References T_Cluster_set::clusters, T_Cluster::data, S_Cluster_PalData::l, T_Cluster::next, NULL, and U_Cluster_Data::pal.

Referenced by Optimize_palette().

◆ CS_Generate_color_table_and_palette()

void CS_Generate_color_table_and_palette ( T_Cluster_set cs,
CT_Tree tc,
T_Components palette,
T_Occurrence_table to 
)

◆ GS_Init()

◆ GS_New()

◆ GS_Delete()

void GS_Delete ( T_Gradient_set ds)

References T_Gradient_set::gradients.

Referenced by Optimize_palette().

◆ GS_Generate()

◆ Optimize_palette()

CT_Tree * Optimize_palette ( T_Bitmap24B  image,
int  size,
T_Components palette,
int  r,
int  g,
int  b 
)

Compute best palette for given picture.

The picture is first depth-reduced to the given r,g,b resolution, then the median cut algorithm is used to find 256 colors which are suitable for the given picture.

Returns
a conversion tree to be used for converting the picture to indexed with the generated palette (with or without dithering).
Parameters
imageThe true-color image for which the palette needs to be optimized
sizein pixels (number of pixels, the height/width doesn't matter)
palettepointer to the space where the palette will be stored (256 entries at most)
rResolution for red
gResolution for green
bResolution for blue

References CS_Compute_colors(), CS_Delete(), CS_Generate(), CS_Generate_color_table_and_palette(), CS_New(), CS_Sort_by_chrominance(), CS_Sort_by_luminance(), CT_delete(), CT_new(), GS_Delete(), GS_Generate(), GS_New(), NULL, OT_count_occurrences(), OT_delete(), and OT_new().

Referenced by Convert_24b_bitmap_to_256().

◆ Modified_value()

int Modified_value ( int  value,
int  modif 
)

Change a value with proper ceiling and flooring.

Referenced by Convert_24b_bitmap_to_256_Floyd_Steinberg().

◆ Convert_24b_bitmap_to_256_Floyd_Steinberg()

void Convert_24b_bitmap_to_256_Floyd_Steinberg ( T_Bitmap256  dest,
T_Bitmap24B  source,
int  width,
int  height,
T_Components palette,
CT_Tree tc 
)

Convert a 24b image to 256 colors (with a given palette and conversion table).

This destroys the 24b picture ! Uses floyd steinberg dithering.

References T_Components::B, CT_get(), T_Components::G, Modified_value(), and T_Components::R.

◆ Convert_24b_bitmap_to_256_nearest_neighbor()

void Convert_24b_bitmap_to_256_nearest_neighbor ( T_Bitmap256  dest,
T_Bitmap24B  source,
int  width,
int  height,
T_Components palette,
CT_Tree tc 
)

Converts from 24b to 256c without dithering, using given conversion table.

References T_Components::B, CT_get(), T_Components::G, and T_Components::R.

Referenced by Convert_24b_bitmap_to_256().

◆ Try_Convert_to_256_Without_Loss()

int Try_Convert_to_256_Without_Loss ( T_Bitmap256  dest,
T_Bitmap24B  source,
int  width,
int  height,
T_Components palette 
)

◆ Convert_24b_bitmap_to_256()

int Convert_24b_bitmap_to_256 ( T_Bitmap256  dest,
T_Bitmap24B  source,
int  width,
int  height,
T_Components palette 
)

Converts a 24 bit picture to 256 color (color reduction)

Parameters
[out]destThe converted 8bpp picture
[in]sourcethe 24bpp picture
[in]widththe width of the picture
[in]heightthe height of the picture
[out]palettethe palette of the converted 8bpp picture
Returns
0 for OK, 1 for error

References Convert_24b_bitmap_to_256_nearest_neighbor(), CT_delete(), NULL, Optimize_palette(), precision_24b, and Try_Convert_to_256_Without_Loss().

Referenced by Load_image(), and Test_Convert_24b_bitmap_to_256().

◆ Set_palette_fake_24b()

void Set_palette_fake_24b ( T_Palette  palette)

Referenced by Load_image().

Variable Documentation

◆ precision_24b

const byte precision_24b[]
static
Initial value:
=
{
8,8,8,
6,6,6,
6,6,5,
5,6,5,
5,5,5,
5,5,4,
4,5,4,
4,4,4,
4,4,3,
3,4,3,
3,3,3,
3,3,2}

Referenced by Convert_24b_bitmap_to_256().