Finished working on the new color lookup system.
There is room for optimization and maybe bugfixing. The cluster table size is now: 511*15 = 7665bytes, this is 1094 times better than the color table. Please test and report your results ! git-svn-id: svn://pulkomandy.tk/GrafX2/trunk@1874 416bcca6-2ee7-4201-b75f-2eb2f807beb1
This commit is contained in:
parent
91e7d459a3
commit
d3a107bb7c
@ -391,7 +391,7 @@ endif
|
||||
.PHONY : all debug release clean depend zip version force install uninstall
|
||||
|
||||
# This is the list of the objects we want to build. Dependancies are built by "make depend" automatically.
|
||||
OBJ = $(OBJDIR)/main.o $(OBJDIR)/init.o $(OBJDIR)/graph.o $(OBJDIR)/sdlscreen.o $(OBJDIR)/misc.o $(OBJDIR)/special.o $(OBJDIR)/buttons.o $(OBJDIR)/palette.o $(OBJDIR)/help.o $(OBJDIR)/operatio.o $(OBJDIR)/pages.o $(OBJDIR)/loadsave.o $(OBJDIR)/readline.o $(OBJDIR)/engine.o $(OBJDIR)/filesel.o $(OBJDIR)/op_c.o $(OBJDIR)/readini.o $(OBJDIR)/saveini.o $(OBJDIR)/shade.o $(OBJDIR)/keyboard.o $(OBJDIR)/io.o $(OBJDIR)/version.o $(OBJDIR)/text.o $(OBJDIR)/SFont.o $(OBJDIR)/setup.o $(OBJDIR)/pxsimple.o $(OBJDIR)/pxtall.o $(OBJDIR)/pxwide.o $(OBJDIR)/pxdouble.o $(OBJDIR)/pxtriple.o $(OBJDIR)/pxtall2.o $(OBJDIR)/pxwide2.o $(OBJDIR)/pxquad.o $(OBJDIR)/windows.o $(OBJDIR)/brush.o $(OBJDIR)/realpath.o $(OBJDIR)/mountlist.o $(OBJDIR)/input.o $(OBJDIR)/hotkeys.o $(OBJDIR)/transform.o $(OBJDIR)/pversion.o $(OBJDIR)/factory.o $(PLATFORMOBJ) $(OBJDIR)/fileformats.o $(OBJDIR)/miscfileformats.o $(OBJDIR)/libraw2crtc.o $(OBJDIR)/brush_ops.o $(OBJDIR)/buttons_effects.o $(OBJDIR)/layers.o $(OBJDIR)/oldies.o $(OBJDIR)/tiles.o
|
||||
OBJ = $(OBJDIR)/main.o $(OBJDIR)/init.o $(OBJDIR)/graph.o $(OBJDIR)/sdlscreen.o $(OBJDIR)/misc.o $(OBJDIR)/special.o $(OBJDIR)/buttons.o $(OBJDIR)/palette.o $(OBJDIR)/help.o $(OBJDIR)/operatio.o $(OBJDIR)/pages.o $(OBJDIR)/loadsave.o $(OBJDIR)/readline.o $(OBJDIR)/engine.o $(OBJDIR)/filesel.o $(OBJDIR)/op_c.o $(OBJDIR)/readini.o $(OBJDIR)/saveini.o $(OBJDIR)/shade.o $(OBJDIR)/keyboard.o $(OBJDIR)/io.o $(OBJDIR)/version.o $(OBJDIR)/text.o $(OBJDIR)/SFont.o $(OBJDIR)/setup.o $(OBJDIR)/pxsimple.o $(OBJDIR)/pxtall.o $(OBJDIR)/pxwide.o $(OBJDIR)/pxdouble.o $(OBJDIR)/pxtriple.o $(OBJDIR)/pxtall2.o $(OBJDIR)/pxwide2.o $(OBJDIR)/pxquad.o $(OBJDIR)/windows.o $(OBJDIR)/brush.o $(OBJDIR)/realpath.o $(OBJDIR)/mountlist.o $(OBJDIR)/input.o $(OBJDIR)/hotkeys.o $(OBJDIR)/transform.o $(OBJDIR)/pversion.o $(OBJDIR)/factory.o $(PLATFORMOBJ) $(OBJDIR)/fileformats.o $(OBJDIR)/miscfileformats.o $(OBJDIR)/libraw2crtc.o $(OBJDIR)/brush_ops.o $(OBJDIR)/buttons_effects.o $(OBJDIR)/layers.o $(OBJDIR)/oldies.o $(OBJDIR)/tiles.o $(OBJDIR)/colorred.o
|
||||
|
||||
SKIN_FILES = ../share/grafx2/skins/skin_classic.png ../share/grafx2/skins/skin_modern.png ../share/grafx2/skins/skin_DPaint.png ../share/grafx2/skins/font_Classic.png ../share/grafx2/skins/font_Fun.png ../share/grafx2/skins/font_Fairlight.png ../share/grafx2/skins/font_Melon.png ../share/grafx2/skins/font_DPaint.png ../share/grafx2/skins/skin_scenish.png ../share/grafx2/skins/font_Seen.png ../share/grafx2/skins/skin_Aurora.png
|
||||
|
||||
|
||||
125
src/Makefile.dep
125
src/Makefile.dep
@ -1,33 +1,34 @@
|
||||
$(OBJDIR)/SFont.o: SFont.c SFont.h
|
||||
$(OBJDIR)/brush.o: brush.c global.h struct.h const.h graph.h misc.h errors.h \
|
||||
windows.h sdlscreen.h brush.h
|
||||
$(OBJDIR)/brush_ops.o: brush_ops.c brush.h struct.h const.h buttons.h engine.h \
|
||||
global.h graph.h misc.h operatio.h pages.h sdlscreen.h windows.h
|
||||
$(OBJDIR)/brush.o: brush.c global.h struct.h const.h graph.h misc.h errors.h \
|
||||
windows.h sdlscreen.h brush.h tiles.h
|
||||
$(OBJDIR)/buttons_effects.o: buttons_effects.c brush.h struct.h const.h \
|
||||
buttons.h engine.h global.h graph.h help.h input.h misc.h pages.h \
|
||||
readline.h sdlscreen.h windows.h tiles.h
|
||||
$(OBJDIR)/buttons.o: buttons.c const.h struct.h global.h misc.h graph.h engine.h \
|
||||
readline.h filesel.h loadsave.h init.h buttons.h operatio.h pages.h \
|
||||
palette.h errors.h readini.h saveini.h shade.h io.h help.h text.h \
|
||||
sdlscreen.h windows.h brush.h input.h special.h setup.h
|
||||
$(OBJDIR)/buttons_effects.o: buttons_effects.c buttons.h struct.h const.h engine.h \
|
||||
global.h graph.h help.h input.h misc.h readline.h sdlscreen.h windows.h \
|
||||
brush.h
|
||||
sdlscreen.h windows.h brush.h input.h special.h tiles.h setup.h
|
||||
$(OBJDIR)/colorred.o: colorred.c
|
||||
$(OBJDIR)/engine.o: engine.c const.h struct.h global.h graph.h misc.h special.h \
|
||||
buttons.h operatio.h shade.h errors.h sdlscreen.h windows.h brush.h \
|
||||
input.h engine.h pages.h layers.h factory.h loadsave.h io.h
|
||||
$(OBJDIR)/factory.o: factory.c brush.h struct.h const.h buttons.h engine.h errors.h \
|
||||
filesel.h loadsave.h global.h graph.h io.h misc.h pages.h readline.h \
|
||||
sdlscreen.h windows.h palette.h input.h help.h realpath.h
|
||||
$(OBJDIR)/factory.o: factory.c brush.h struct.h const.h buttons.h engine.h \
|
||||
errors.h filesel.h loadsave.h global.h graph.h io.h misc.h pages.h \
|
||||
readline.h sdlscreen.h windows.h palette.h input.h help.h realpath.h \
|
||||
setup.h
|
||||
$(OBJDIR)/fileformats.o: fileformats.c errors.h global.h struct.h const.h \
|
||||
loadsave.h misc.h io.h windows.h pages.h
|
||||
$(OBJDIR)/filesel.o: filesel.c const.h struct.h global.h misc.h errors.h io.h \
|
||||
windows.h sdlscreen.h loadsave.h mountlist.h engine.h readline.h input.h \
|
||||
help.h filesel.h
|
||||
windows.h sdlscreen.h loadsave.h mountlist.h engine.h readline.h \
|
||||
input.h help.h filesel.h
|
||||
$(OBJDIR)/graph.o: graph.c global.h struct.h const.h engine.h buttons.h pages.h \
|
||||
errors.h sdlscreen.h graph.h misc.h pxsimple.h pxtall.h pxwide.h \
|
||||
pxdouble.h pxtriple.h pxwide2.h pxtall2.h pxquad.h windows.h input.h \
|
||||
brush.h
|
||||
$(OBJDIR)/help.o: help.c const.h struct.h global.h misc.h engine.h helpfile.h \
|
||||
help.h sdlscreen.h text.h keyboard.h windows.h input.h hotkeys.h \
|
||||
errors.h pages.h
|
||||
brush.h tiles.h
|
||||
$(OBJDIR)/help.o: help.c haiku.h struct.h const.h global.h misc.h engine.h \
|
||||
helpfile.h help.h sdlscreen.h text.h keyboard.h windows.h input.h \
|
||||
hotkeys.h errors.h pages.h
|
||||
$(OBJDIR)/hotkeys.o: hotkeys.c struct.h const.h global.h hotkeys.h
|
||||
$(OBJDIR)/init.o: init.c buttons.h struct.h const.h errors.h global.h graph.h \
|
||||
init.h io.h factory.h help.h hotkeys.h keyboard.h loadsave.h misc.h \
|
||||
@ -37,70 +38,76 @@ $(OBJDIR)/input.o: input.c global.h struct.h const.h keyboard.h sdlscreen.h \
|
||||
windows.h errors.h misc.h buttons.h input.h loadsave.h
|
||||
$(OBJDIR)/io.o: io.c struct.h const.h io.h realpath.h
|
||||
$(OBJDIR)/keyboard.o: keyboard.c global.h struct.h const.h keyboard.h
|
||||
$(OBJDIR)/layers.o: layers.c const.h struct.h global.h windows.h engine.h pages.h \
|
||||
sdlscreen.h input.h help.h misc.h
|
||||
$(OBJDIR)/layers.o: layers.c const.h struct.h global.h windows.h engine.h \
|
||||
pages.h sdlscreen.h input.h help.h misc.h readline.h
|
||||
$(OBJDIR)/libraw2crtc.o: libraw2crtc.c const.h global.h struct.h loadsave.h
|
||||
$(OBJDIR)/loadsave.o: loadsave.c buttons.h struct.h const.h errors.h global.h io.h \
|
||||
loadsave.h misc.h graph.h op_c.h pages.h palette.h sdlscreen.h windows.h \
|
||||
engine.h brush.h setup.h
|
||||
$(OBJDIR)/main.o: main.c const.h struct.h global.h graph.h misc.h init.h buttons.h \
|
||||
engine.h pages.h loadsave.h sdlscreen.h errors.h readini.h saveini.h \
|
||||
io.h text.h setup.h windows.h brush.h palette.h realpath.h input.h \
|
||||
help.h
|
||||
$(OBJDIR)/misc.o: misc.c struct.h const.h sdlscreen.h global.h errors.h buttons.h \
|
||||
engine.h misc.h keyboard.h windows.h palette.h input.h graph.h pages.h
|
||||
$(OBJDIR)/miscfileformats.o: miscfileformats.c engine.h struct.h const.h errors.h \
|
||||
global.h io.h libraw2crtc.h loadsave.h misc.h sdlscreen.h windows.h
|
||||
$(OBJDIR)/mountlist.o: mountlist.c
|
||||
$(OBJDIR)/op_c.o: op_c.c op_c.h struct.h const.h errors.h global.h engine.h \
|
||||
windows.h
|
||||
$(OBJDIR)/operatio.o: operatio.c const.h struct.h global.h misc.h engine.h graph.h \
|
||||
operatio.h buttons.h pages.h errors.h sdlscreen.h brush.h windows.h \
|
||||
input.h
|
||||
$(OBJDIR)/loadsave.o: loadsave.c buttons.h struct.h const.h errors.h global.h \
|
||||
io.h loadsave.h misc.h graph.h op_c.h pages.h palette.h sdlscreen.h \
|
||||
windows.h engine.h brush.h setup.h
|
||||
$(OBJDIR)/main.o: main.c const.h struct.h global.h graph.h misc.h init.h \
|
||||
buttons.h engine.h pages.h loadsave.h sdlscreen.h errors.h readini.h \
|
||||
saveini.h io.h text.h setup.h windows.h brush.h palette.h realpath.h \
|
||||
input.h help.h
|
||||
$(OBJDIR)/misc.o: misc.c struct.h const.h sdlscreen.h global.h errors.h \
|
||||
buttons.h engine.h misc.h keyboard.h windows.h palette.h input.h \
|
||||
graph.h pages.h
|
||||
$(OBJDIR)/miscfileformats.o: miscfileformats.c engine.h struct.h const.h \
|
||||
errors.h global.h io.h libraw2crtc.h \
|
||||
/boot/develop/abi/x86/gcc2/tools/gcc-2.95.3-haiku-100818/lib/gcc-lib/i586-pc-haiku/2.95.3-haiku-100818/include/limits.h \
|
||||
loadsave.h misc.h sdlscreen.h windows.h oldies.h
|
||||
$(OBJDIR)/mountlist.o: mountlist.c mountlist.h
|
||||
$(OBJDIR)/oldies.o: oldies.c struct.h const.h global.h errors.h misc.h palette.h
|
||||
$(OBJDIR)/op_c.o: op_c.c op_c.h struct.h const.h errors.h global.h \
|
||||
/boot/develop/abi/x86/gcc2/tools/gcc-2.95.3-haiku-100818/lib/gcc-lib/i586-pc-haiku/2.95.3-haiku-100818/include/limits.h \
|
||||
engine.h windows.h
|
||||
$(OBJDIR)/operatio.o: operatio.c const.h struct.h global.h misc.h engine.h \
|
||||
graph.h operatio.h buttons.h pages.h errors.h sdlscreen.h brush.h \
|
||||
windows.h input.h
|
||||
$(OBJDIR)/pages.o: pages.c global.h struct.h const.h pages.h errors.h loadsave.h \
|
||||
misc.h windows.h
|
||||
$(OBJDIR)/palette.o: palette.c const.h struct.h global.h misc.h engine.h readline.h \
|
||||
buttons.h pages.h help.h sdlscreen.h errors.h op_c.h windows.h input.h \
|
||||
palette.h shade.h
|
||||
$(OBJDIR)/palette_test.o: palette_test.c const.h struct.h global.h misc.h engine.h \
|
||||
$(OBJDIR)/palette.o: palette.c const.h struct.h global.h misc.h engine.h \
|
||||
readline.h buttons.h pages.h help.h sdlscreen.h errors.h op_c.h \
|
||||
windows.h input.h palette.h shade.h
|
||||
$(OBJDIR)/pversion.o: pversion.c
|
||||
$(OBJDIR)/pxdouble.o: pxdouble.c global.h struct.h const.h sdlscreen.h misc.h \
|
||||
graph.h pxdouble.h pxwide.h
|
||||
$(OBJDIR)/pxquad.o: pxquad.c global.h struct.h const.h sdlscreen.h misc.h graph.h \
|
||||
pxquad.h
|
||||
$(OBJDIR)/pxquad.o: pxquad.c global.h struct.h const.h sdlscreen.h misc.h \
|
||||
graph.h pxquad.h
|
||||
$(OBJDIR)/pxsimple.o: pxsimple.c global.h struct.h const.h sdlscreen.h misc.h \
|
||||
graph.h pxsimple.h
|
||||
$(OBJDIR)/pxtall.o: pxtall.c global.h struct.h const.h sdlscreen.h misc.h graph.h \
|
||||
pxtall.h pxsimple.h
|
||||
$(OBJDIR)/pxtall2.o: pxtall2.c global.h struct.h const.h sdlscreen.h misc.h graph.h \
|
||||
pxtall2.h
|
||||
$(OBJDIR)/pxtall.o: pxtall.c global.h struct.h const.h sdlscreen.h misc.h \
|
||||
graph.h pxtall.h pxsimple.h
|
||||
$(OBJDIR)/pxtall2.o: pxtall2.c global.h struct.h const.h sdlscreen.h misc.h \
|
||||
graph.h pxtall2.h
|
||||
$(OBJDIR)/pxtriple.o: pxtriple.c global.h struct.h const.h sdlscreen.h misc.h \
|
||||
graph.h pxtriple.h
|
||||
$(OBJDIR)/pxwide.o: pxwide.c global.h struct.h const.h sdlscreen.h misc.h graph.h \
|
||||
pxwide.h
|
||||
$(OBJDIR)/pxwide2.o: pxwide2.c global.h struct.h const.h sdlscreen.h misc.h graph.h \
|
||||
pxwide2.h
|
||||
$(OBJDIR)/readini.o: readini.c const.h errors.h global.h struct.h misc.h readini.h \
|
||||
setup.h realpath.h io.h
|
||||
$(OBJDIR)/pxwide.o: pxwide.c global.h struct.h const.h sdlscreen.h misc.h \
|
||||
graph.h pxwide.h
|
||||
$(OBJDIR)/pxwide2.o: pxwide2.c global.h struct.h const.h sdlscreen.h misc.h \
|
||||
graph.h pxwide2.h
|
||||
$(OBJDIR)/readini.o: readini.c const.h errors.h global.h struct.h misc.h \
|
||||
readini.h setup.h realpath.h io.h
|
||||
$(OBJDIR)/readline.o: readline.c const.h struct.h global.h misc.h errors.h \
|
||||
sdlscreen.h readline.h windows.h input.h engine.h
|
||||
$(OBJDIR)/realpath.o: realpath.c
|
||||
$(OBJDIR)/saveini.o: saveini.c const.h global.h struct.h readini.h io.h errors.h \
|
||||
misc.h saveini.h setup.h
|
||||
$(OBJDIR)/sdlscreen.o: sdlscreen.c global.h struct.h const.h sdlscreen.h errors.h \
|
||||
misc.h
|
||||
$(OBJDIR)/sdlscreen.o: sdlscreen.c global.h struct.h const.h sdlscreen.h \
|
||||
errors.h misc.h
|
||||
$(OBJDIR)/setup.o: setup.c struct.h const.h io.h setup.h
|
||||
$(OBJDIR)/SFont.o: SFont.c SFont.h
|
||||
$(OBJDIR)/shade.o: shade.c global.h struct.h const.h graph.h engine.h errors.h \
|
||||
misc.h readline.h help.h sdlscreen.h windows.h input.h shade.h
|
||||
$(OBJDIR)/special.o: special.c const.h struct.h global.h graph.h engine.h windows.h \
|
||||
special.h pages.h misc.h buttons.h
|
||||
$(OBJDIR)/special.o: special.c const.h struct.h global.h graph.h engine.h \
|
||||
windows.h special.h pages.h misc.h buttons.h
|
||||
$(OBJDIR)/text.o: text.c SFont.h struct.h const.h global.h sdlscreen.h io.h \
|
||||
errors.h windows.h misc.h setup.h
|
||||
$(OBJDIR)/tiles.o: tiles.c
|
||||
$(OBJDIR)/transform.o: transform.c global.h struct.h const.h transform.h engine.h \
|
||||
sdlscreen.h windows.h input.h help.h misc.h readline.h buttons.h pages.h
|
||||
$(OBJDIR)/tiles.o: tiles.c struct.h const.h global.h graph.h sdlscreen.h \
|
||||
engine.h windows.h input.h misc.h tiles.h
|
||||
$(OBJDIR)/transform.o: transform.c global.h struct.h const.h transform.h \
|
||||
engine.h sdlscreen.h windows.h input.h help.h misc.h readline.h \
|
||||
buttons.h pages.h tiles.h
|
||||
$(OBJDIR)/version.o: version.c
|
||||
$(OBJDIR)/windows.o: windows.c windows.h struct.h const.h engine.h errors.h \
|
||||
global.h graph.h input.h misc.h op_c.h readline.h sdlscreen.h palette.h
|
||||
global.h graph.h input.h misc.h op_c.h readline.h sdlscreen.h \
|
||||
palette.h
|
||||
|
||||
107
src/colorred.c
107
src/colorred.c
@ -23,6 +23,7 @@
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "colorred.h"
|
||||
|
||||
@ -35,11 +36,19 @@ but :
|
||||
|
||||
CT_Node* CT_new() {return NULL;}
|
||||
|
||||
void CT_set(CT_Node* colorTree, byte Rmin, byte Gmin, byte Bmin,
|
||||
// debug helper
|
||||
void CT_Print(CT_Node* node)
|
||||
{
|
||||
printf("R %d %d\tG %d %d\tB %d %d\ti %d\n",
|
||||
node->Rmin, node->Rmax, node->Gmin, node->Gmax,
|
||||
node->Bmin, node->Bmax, node->index);
|
||||
}
|
||||
|
||||
void CT_set(CT_Node** colorTree, byte Rmin, byte Gmin, byte Bmin,
|
||||
byte Rmax, byte Gmax, byte Bmax, byte index)
|
||||
{
|
||||
int i;
|
||||
CT_Node* parent = colorTree;
|
||||
CT_Node* parent;
|
||||
// Create and setup node
|
||||
CT_Node* node = malloc(sizeof(CT_Node));
|
||||
|
||||
@ -51,65 +60,77 @@ void CT_set(CT_Node* colorTree, byte Rmin, byte Gmin, byte Bmin,
|
||||
node->Bmax = Bmax;
|
||||
node->index = index;
|
||||
|
||||
for(i = 0; i < 7; i++)
|
||||
printf("Add node:");
|
||||
CT_Print(node);
|
||||
|
||||
for(i = 0; i < 2; i++)
|
||||
node->children[i] = NULL;
|
||||
|
||||
// Now insert it in tree
|
||||
|
||||
parent = *colorTree;
|
||||
if (parent == NULL) {
|
||||
// This is our first node.
|
||||
colorTree = node;
|
||||
*colorTree = node;
|
||||
} else for(;;) {
|
||||
// Find where to insert ourselves
|
||||
// (clusters are non-intersecting, so there is no need to check for that)
|
||||
int where = 0;
|
||||
if (parent->Rmin < node->Rmin)
|
||||
where += 4;
|
||||
if (parent->Gmin < node->Gmin)
|
||||
where += 2;
|
||||
if (parent->Bmin < node->Bmin)
|
||||
where += 1;
|
||||
|
||||
// TODO - we always insert downwards, maybe we should try to keep
|
||||
// the tree balanced...
|
||||
// pre-condition: the parent we're looking at is a superset of the node we're inserting
|
||||
// it may have 0, 1, or 2 child
|
||||
|
||||
if (parent->children[where] == NULL)
|
||||
// 0 child: insert as child 0
|
||||
// 1 child: either we're included in the child, and recurse, or we''re not, and insert at child 1
|
||||
// 2 child: one of them has to be a superset of the node.
|
||||
|
||||
if (parent->children[0] == NULL)
|
||||
{
|
||||
// insert!
|
||||
parent->children[where] = node;
|
||||
parent->children[0] = node;
|
||||
break;
|
||||
} else {
|
||||
// recurse
|
||||
parent = parent->children[where];
|
||||
CT_Node* child0 = parent->children[0];
|
||||
if (child0->Rmin <= node->Rmin
|
||||
&& child0->Gmin <= node->Gmin
|
||||
&& child0->Bmin <= node->Bmin
|
||||
&& child0->Rmax >= node->Rmax
|
||||
&& child0->Gmax >= node->Gmax
|
||||
&& child0->Bmax >= node->Bmax
|
||||
) {
|
||||
parent = child0;
|
||||
} else if(parent->children[1] == NULL)
|
||||
{
|
||||
parent->children[1] = node;
|
||||
break;
|
||||
} else {
|
||||
parent = parent->children[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
byte CT_get(CT_Node* node, byte r, byte g, byte b)
|
||||
{
|
||||
int wheremin = 0;
|
||||
int wheremax = 0;
|
||||
// pre condition: node contains (rgb)
|
||||
// find the leaf that also contains (rgb)
|
||||
|
||||
if (node->Rmin < r)
|
||||
wheremin += 4;
|
||||
if (node->Gmin < g)
|
||||
wheremin += 2;
|
||||
if (node->Bmin < b)
|
||||
wheremin += 1;
|
||||
|
||||
if (node->Rmax < r)
|
||||
wheremin += 4;
|
||||
if (node->Gmax < g)
|
||||
wheremin += 2;
|
||||
if (node->Bmax < b)
|
||||
wheremin += 1;
|
||||
|
||||
if (wheremin == 7 && wheremax == 0)
|
||||
{
|
||||
// Found it!
|
||||
return node->index;
|
||||
} else {
|
||||
return CT_get(node->children[wheremin], r, g, b);
|
||||
for(;;) {
|
||||
if(node->children[0] == NULL)
|
||||
return node->index;
|
||||
else {
|
||||
// Left or right ?
|
||||
CT_Node* child0 = node->children[0];
|
||||
if (child0->Rmin <= r
|
||||
&& child0->Gmin <= g
|
||||
&& child0->Bmin <= b
|
||||
&& child0->Rmax >= r
|
||||
&& child0->Gmax >= g
|
||||
&& child0->Bmax >= b
|
||||
) {
|
||||
// left
|
||||
node = child0;
|
||||
} else {
|
||||
// right
|
||||
node = node->children[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -118,7 +139,7 @@ void CT_delete(CT_Node* tree)
|
||||
int i;
|
||||
if (tree == NULL)
|
||||
return;
|
||||
for (i = 0; i < 8; i++)
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
CT_delete(tree->children[i]);
|
||||
}
|
||||
|
||||
@ -46,18 +46,26 @@ typedef struct CT_Node_s
|
||||
byte Gmax;
|
||||
byte Bmax;
|
||||
|
||||
// possible optimization: a cluster has either two childs or a color index.
|
||||
// if the first child is NULL, then the other can be used to store the index
|
||||
// when the tree is being built, a node may have child0 set and not child1, but not the reverse)
|
||||
|
||||
// possible optimization: there can't be more than 511 clusters in the tree
|
||||
// for a 256 color picture, so use int16 as pointers and store everything in a table :
|
||||
// * makes them smaller
|
||||
// * helps with cache locality
|
||||
|
||||
// palette index (valid iff any child is NULL)
|
||||
byte index;
|
||||
|
||||
// child nodes
|
||||
struct CT_Node_s* children[8];
|
||||
//rgb rgB rGb rGB Rgb RgB RGb RGB
|
||||
struct CT_Node_s* children[2];
|
||||
} CT_Node;
|
||||
|
||||
CT_Node* CT_new();
|
||||
void CT_delete(CT_Node* t);
|
||||
byte CT_get(CT_Node* t,byte r,byte g,byte b);
|
||||
void CT_set(CT_Node* colorTree, byte Rmin, byte Gmin, byte Bmin,
|
||||
void CT_set(CT_Node** colorTree, byte Rmin, byte Gmin, byte Bmin,
|
||||
byte Rmax, byte Gmax, byte Bmax, byte index);
|
||||
|
||||
#endif
|
||||
|
||||
140
src/op_c.c
140
src/op_c.c
@ -30,6 +30,7 @@
|
||||
|
||||
#include "op_c.h"
|
||||
#include "errors.h"
|
||||
#include "colorred.h"
|
||||
|
||||
int Convert_24b_bitmap_to_256_fast(T_Bitmap256 dest,T_Bitmap24B source,int width,int height,T_Components * palette);
|
||||
|
||||
@ -178,95 +179,6 @@ long Perceptual_lightness(T_Components *color)
|
||||
19*color->B*19*color->B;
|
||||
}
|
||||
|
||||
// Conversion table handlers
|
||||
// The conversion table is built after a run of the median cut algorithm and is
|
||||
// used to find the best color index for a given (RGB) color. GIMP avoids
|
||||
// creating the whole table and only create parts of it when they are actually
|
||||
// needed. This may or may not be faster
|
||||
|
||||
/// Creates a new conversion table
|
||||
/// params: bumber of bits for R, G, B (precision)
|
||||
T_Conversion_table * CT_new(int nbb_r,int nbb_g,int nbb_b)
|
||||
{
|
||||
T_Conversion_table * n;
|
||||
int size;
|
||||
|
||||
n=(T_Conversion_table *)malloc(sizeof(T_Conversion_table));
|
||||
if (n!=NULL)
|
||||
{
|
||||
// Copy the passed parameters
|
||||
n->nbb_r=nbb_r;
|
||||
n->nbb_g=nbb_g;
|
||||
n->nbb_b=nbb_b;
|
||||
|
||||
// Calculate the others
|
||||
|
||||
// Value ranges (max value actually)
|
||||
n->rng_r=(1<<nbb_r);
|
||||
n->rng_g=(1<<nbb_g);
|
||||
n->rng_b=(1<<nbb_b);
|
||||
|
||||
// Shifts
|
||||
n->dec_r=nbb_g+nbb_b;
|
||||
n->dec_g=nbb_b;
|
||||
n->dec_b=0;
|
||||
|
||||
// Reductions (how many bits are lost)
|
||||
n->red_r=8-nbb_r;
|
||||
n->red_g=8-nbb_g;
|
||||
n->red_b=8-nbb_b;
|
||||
|
||||
// Allocate the table
|
||||
size=(n->rng_r)*(n->rng_g)*(n->rng_b);
|
||||
n->table=(byte *)calloc(size, 1);
|
||||
if (n->table == NULL)
|
||||
{
|
||||
// Not enough memory
|
||||
free(n);
|
||||
n=NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
/// Delete a conversion table and release its memory
|
||||
void CT_delete(T_Conversion_table * t)
|
||||
{
|
||||
free(t->table);
|
||||
free(t);
|
||||
t = NULL;
|
||||
}
|
||||
|
||||
|
||||
/// Get the best palette index for an (R, G, B) color
|
||||
byte CT_get(T_Conversion_table * t,int r,int g,int b)
|
||||
{
|
||||
int index;
|
||||
|
||||
// Reduce the number of bits to the table precision
|
||||
r=(r>>t->red_r);
|
||||
g=(g>>t->red_g);
|
||||
b=(b>>t->red_b);
|
||||
|
||||
// Find the nearest color
|
||||
index=(r<<t->dec_r) | (g<<t->dec_g) | (b<<t->dec_b);
|
||||
|
||||
return t->table[index];
|
||||
}
|
||||
|
||||
|
||||
/// Set an entry of the table, index (RGB), value i
|
||||
void CT_set(T_Conversion_table * t,int r,int g,int b,byte i)
|
||||
{
|
||||
int index;
|
||||
|
||||
index=(r<<t->dec_r) | (g<<t->dec_g) | (b<<t->dec_b);
|
||||
t->table[index]=i;
|
||||
}
|
||||
|
||||
|
||||
// Handlers for the occurences tables
|
||||
// This table is used to count the occurence of an (RGB) pixel value in the
|
||||
// source 24bit image. These count are then used by the median cut algorithm to
|
||||
@ -883,7 +795,8 @@ void CS_Set(T_Cluster_set * cs,T_Cluster * c)
|
||||
// 4) We pack the 2 resulting boxes again to leave no empty space between the box border and the first pixel
|
||||
// 5) We take the box with the biggest number of pixels inside and we split it again
|
||||
// 6) Iterate until there are 256 boxes. Associate each of them to its middle color
|
||||
void CS_Generate(T_Cluster_set * cs, T_Occurrence_table * to)
|
||||
// At the same time, put the split clusters in the color tree for later palette lookup
|
||||
void CS_Generate(T_Cluster_set * cs, T_Occurrence_table * to, CT_Node** colorTree)
|
||||
{
|
||||
T_Cluster current;
|
||||
T_Cluster Nouveau1;
|
||||
@ -895,6 +808,10 @@ void CS_Generate(T_Cluster_set * cs, T_Occurrence_table * to)
|
||||
// Get the biggest one
|
||||
CS_Get(cs,¤t);
|
||||
|
||||
// We're going to split, so add the cluster to the colortree
|
||||
CT_set(colorTree,current.Rmin, current.Gmin, current.Bmin,
|
||||
current.Rmax, current.Vmax, current.Bmax, 0);
|
||||
|
||||
// Split it
|
||||
Cluster_split(¤t, &Nouveau1, &Nouveau2, current.plus_large, to);
|
||||
|
||||
@ -994,10 +911,9 @@ void CS_Sort_by_luminance(T_Cluster_set * cs)
|
||||
|
||||
|
||||
/// Generates the palette from the clusters, then the conversion table to map (RGB) to a palette index
|
||||
void CS_Generate_color_table_and_palette(T_Cluster_set * cs,T_Conversion_table * tc,T_Components * palette)
|
||||
void CS_Generate_color_table_and_palette(T_Cluster_set * cs,CT_Node** tc,T_Components * palette)
|
||||
{
|
||||
int index;
|
||||
int r,g,b;
|
||||
T_Cluster* current = cs->clusters;
|
||||
|
||||
for (index=0;index<cs->nb;index++)
|
||||
@ -1006,10 +922,8 @@ void CS_Generate_color_table_and_palette(T_Cluster_set * cs,T_Conversion_table *
|
||||
palette[index].G=current->g;
|
||||
palette[index].B=current->b;
|
||||
|
||||
for (r=current->Rmin; r<=current->Rmax; r++)
|
||||
for (g=current->Gmin;g<=current->Vmax;g++)
|
||||
for (b=current->Bmin;b<=current->Bmax;b++)
|
||||
CT_set(tc,r,g,b,index);
|
||||
CT_set(tc,current->Rmin, current->Gmin, current->Bmin,
|
||||
current->Rmax, current->Vmax, current->Bmax, index);
|
||||
current = current->next;
|
||||
}
|
||||
}
|
||||
@ -1120,11 +1034,11 @@ void GS_Generate(T_Gradient_set * ds,T_Cluster_set * cs)
|
||||
|
||||
|
||||
/// Compute best palette for given picture.
|
||||
T_Conversion_table * Optimize_palette(T_Bitmap24B image, int size,
|
||||
CT_Node* Optimize_palette(T_Bitmap24B image, int size,
|
||||
T_Components * palette, int r, int g, int b)
|
||||
{
|
||||
T_Occurrence_table * to;
|
||||
T_Conversion_table * tc;
|
||||
CT_Node* tc;
|
||||
T_Cluster_set * cs;
|
||||
T_Gradient_set * ds;
|
||||
|
||||
@ -1135,13 +1049,14 @@ T_Conversion_table * Optimize_palette(T_Bitmap24B image, int size,
|
||||
if (to == NULL)
|
||||
return 0;
|
||||
|
||||
tc = CT_new(r, g, b);
|
||||
tc = CT_new();
|
||||
/*
|
||||
if (tc == NULL)
|
||||
{
|
||||
OT_delete(to);
|
||||
return 0;
|
||||
OT_delete(to);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*/
|
||||
// Count pixels for each color
|
||||
OT_count_occurrences(to, image, size);
|
||||
|
||||
@ -1156,7 +1071,7 @@ T_Conversion_table * Optimize_palette(T_Bitmap24B image, int size,
|
||||
// Ok, everything was allocated
|
||||
|
||||
// Generate the cluster set with median cut algorithm
|
||||
CS_Generate(cs, to);
|
||||
CS_Generate(cs, to, &tc);
|
||||
//CS_Check(cs);
|
||||
|
||||
// Compute the color data for each cluster (palette entry + HL)
|
||||
@ -1176,7 +1091,7 @@ T_Conversion_table * Optimize_palette(T_Bitmap24B image, int size,
|
||||
//CS_Check(cs);
|
||||
|
||||
// And finally generate the conversion table to map RGB > pal. index
|
||||
CS_Generate_color_table_and_palette(cs, tc, palette);
|
||||
CS_Generate_color_table_and_palette(cs, &tc, palette);
|
||||
//CS_Check(cs);
|
||||
|
||||
CS_Delete(cs);
|
||||
@ -1204,7 +1119,7 @@ int Modified_value(int value,int modif)
|
||||
/// Convert a 24b image to 256 colors (with a given palette and conversion table)
|
||||
/// This destroys the 24b picture !
|
||||
/// Uses floyd steinberg dithering.
|
||||
void Convert_24b_bitmap_to_256_Floyd_Steinberg(T_Bitmap256 dest,T_Bitmap24B source,int width,int height,T_Components * palette,T_Conversion_table * tc)
|
||||
void Convert_24b_bitmap_to_256_Floyd_Steinberg(T_Bitmap256 dest,T_Bitmap24B source,int width,int height,T_Components * palette,CT_Node* tc)
|
||||
{
|
||||
T_Bitmap24B current;
|
||||
T_Bitmap24B c_plus1;
|
||||
@ -1300,7 +1215,7 @@ void Convert_24b_bitmap_to_256_Floyd_Steinberg(T_Bitmap256 dest,T_Bitmap24B sour
|
||||
/// Converts from 24b to 256c without dithering, using given conversion table
|
||||
void Convert_24b_bitmap_to_256_nearest_neighbor(T_Bitmap256 dest,
|
||||
T_Bitmap24B source, int width, int height, __attribute__((unused)) T_Components * palette,
|
||||
T_Conversion_table * tc)
|
||||
CT_Node* tc)
|
||||
{
|
||||
T_Bitmap24B current;
|
||||
T_Bitmap256 d;
|
||||
@ -1359,19 +1274,20 @@ int Convert_24b_bitmap_to_256(T_Bitmap256 dest,T_Bitmap24B source,int width,int
|
||||
return Convert_24b_bitmap_to_256_fast(dest, source, width, height, palette);
|
||||
|
||||
#else
|
||||
T_Conversion_table * table; // table de conversion
|
||||
CT_Node* table; // table de conversion
|
||||
int ip; // index de précision pour la conversion
|
||||
|
||||
// On essaye d'obtenir une table de conversion qui loge en mémoire, avec la
|
||||
// meilleure précision possible
|
||||
for (ip=0;ip<(10*3);ip+=3)
|
||||
{
|
||||
table=Optimize_palette(source,width*height,palette,precision_24b[ip+0],
|
||||
precision_24b[ip+1],precision_24b[ip+2]);
|
||||
if (table!=0)
|
||||
break;
|
||||
table = Optimize_palette(source,width*height,palette,
|
||||
precision_24b[ip], precision_24b[ip+1], precision_24b[ip+2]);
|
||||
if (table != NULL)
|
||||
break;
|
||||
}
|
||||
if (table!=0)
|
||||
|
||||
if (table!=NULL)
|
||||
{
|
||||
//Convert_24b_bitmap_to_256_Floyd_Steinberg(dest,source,width,height,palette,table);
|
||||
Convert_24b_bitmap_to_256_nearest_neighbor(dest,source,width,height,palette,table);
|
||||
|
||||
42
src/op_c.h
42
src/op_c.h
@ -30,6 +30,7 @@
|
||||
#define _OP_C_H_
|
||||
|
||||
#include "struct.h"
|
||||
#include "colorred.h"
|
||||
|
||||
//////////////////////////////////////////////// Définition des types de base
|
||||
|
||||
@ -37,32 +38,6 @@ typedef T_Components * T_Bitmap24B;
|
||||
typedef byte * T_Bitmap256;
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////// Définition d'une table de conversion
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int nbb_r; // Nb de bits de précision sur les rouges
|
||||
int nbb_g; // Nb de bits de précision sur les verts
|
||||
int nbb_b; // Nb de bits de précision sur les bleu
|
||||
|
||||
int rng_r; // Nb de valeurs sur les rouges (= 1<<nbb_r)
|
||||
int rng_g; // Nb de valeurs sur les verts (= 1<<nbb_g)
|
||||
int rng_b; // Nb de valeurs sur les bleus (= 1<<nbb_b)
|
||||
|
||||
int dec_r; // Coefficient multiplicateur d'accès dans la table (= nbb_g+nbb_b)
|
||||
int dec_g; // Coefficient multiplicateur d'accès dans la table (= nbb_b)
|
||||
int dec_b; // Coefficient multiplicateur d'accès dans la table (= 0)
|
||||
|
||||
int red_r; // Coefficient réducteur de traduction d'une couleur rouge (= 8-nbb_r)
|
||||
int red_g; // Coefficient réducteur de traduction d'une couleur verte (= 8-nbb_g)
|
||||
int red_b; // Coefficient réducteur de traduction d'une couleur bleue (= 8-nbb_b)
|
||||
|
||||
byte * table;
|
||||
} T_Conversion_table;
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////// Définition d'une table d'occurences
|
||||
|
||||
typedef struct
|
||||
@ -146,17 +121,6 @@ typedef struct
|
||||
T_Gradient * gradients; // Les dégradés
|
||||
} T_Gradient_set;
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////// Méthodes de gestion des tables de conversion //
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
T_Conversion_table * CT_new(int nbb_r,int nbb_g,int nbb_b);
|
||||
void CT_delete(T_Conversion_table * t);
|
||||
byte CT_get(T_Conversion_table * t,int r,int g,int b);
|
||||
void CT_set(T_Conversion_table * t,int r,int g,int b,byte i);
|
||||
|
||||
void RGB_to_HSL(int r, int g,int b, byte* h, byte*s, byte* l);
|
||||
void HSL_to_RGB(byte h, byte s, byte l, byte* r, byte* g, byte* b);
|
||||
|
||||
@ -194,9 +158,9 @@ T_Cluster_set * CS_New(int nbmax,T_Occurrence_table * to);
|
||||
void CS_Delete(T_Cluster_set * cs);
|
||||
void CS_Get(T_Cluster_set * cs,T_Cluster * c);
|
||||
void CS_Set(T_Cluster_set * cs,T_Cluster * c);
|
||||
void CS_Generate(T_Cluster_set * cs,T_Occurrence_table * to);
|
||||
void CS_Generate(T_Cluster_set * cs,T_Occurrence_table * to, CT_Node** colorTree);
|
||||
void CS_Compute_colors(T_Cluster_set * cs,T_Occurrence_table * to);
|
||||
void CS_Generate_color_table_and_palette(T_Cluster_set * cs,T_Conversion_table * tc,T_Components * palette);
|
||||
void CS_Generate_color_table_and_palette(T_Cluster_set * cs,CT_Node** tc,T_Components * palette);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////// Méthodes de gestion des ensembles de dégradés //
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user