MOVES/BGI/OCTREE.C
2021-09-08 21:30:32 +02:00

182 lines
4.3 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <string.h>
#include "alloc.h"
#include "dos.h"
#include "quant.h"
#include "octree.h"
#define TESTBIT(a,i) ( ((a) >> (i)) & 1)
#define MAXDEPTH 8
#define BYTE unsigned char
UCHAR palette [MAXCOLORS][3];
static UINT size;
static UINT reducelevel;
static UINT leaflevel;
static OCTREE tree;
static BYTE rgb_mio[3];
static OCTREE reducelist[MAXDEPTH + 1];
static unsigned char quant_r,
quant_g,
quant_b;
/* Quantiza seg£n TESTBIT, pero solamente de retorno */
static char quant2(OCTREE tree)
{
if (tree->leaf) return(tree->colorindex);
else return(quant2(tree->next[
TESTBIT(quant_r, MAXDEPTH - tree->level) * 4 +
TESTBIT(quant_g, MAXDEPTH - tree->level) * 2 +
TESTBIT(quant_b, MAXDEPTH - tree->level)]));
}
/* devuelve el indice a la paleta quantizada de acuerdo con RGB apuntado */
int pal_index(UCHAR *p)
{
quant_r = p[RED];
quant_g = p[GREEN];
quant_b = p[BLUE];
return quant2(tree);
}
static double init_Cfactor;
static UINT init_col_num;
static void initpalette(OCTREE tree)
{
UINT j;
if (tree == NULL) return;
if (tree->leaf || tree->level == leaflevel) {
palette[init_col_num][RED] = (char) ((init_Cfactor * tree->rgbsum.r) / tree->colorcount + .5);
palette[init_col_num][GREEN] = (char) ((init_Cfactor * tree->rgbsum.g) / tree->colorcount + .5);
palette[init_col_num][BLUE] = (char) ((init_Cfactor * tree->rgbsum.b) / tree->colorcount + .5);
tree->colorindex = init_col_num;
tree->leaf = TRUE;
init_col_num++;
} else {
for (j = 0; j < 8; j++)
initpalette(tree->next[j]);
}
}
/* calcula la paleta de acuerdo con un factor introducido */
UINT calc_palette(UINT i, double Cfactor)
{
init_Cfactor = Cfactor;
init_col_num = i;
initpalette(tree);
return init_col_num;
}
static void newandinit(OCTREE *tree, UINT depth)
{
unsigned long rest;
*tree = (OCTREE)calloc(1,sizeof(struct node));
if (*tree == NULL) {
rest=coreleft();
printf("No hay bastante Memoria");
exit(1);
}
(*tree)->level = depth;
(*tree)->leaf = (depth >= leaflevel);
if ((*tree)->leaf)
size++;
}
static void getreduceable(OCTREE *node)
{
UINT newreducelevel;
newreducelevel = reducelevel;
while (reducelist[newreducelevel] == NULL)
newreducelevel--;
*node = reducelist[newreducelevel];
reducelist[newreducelevel] =
reducelist[newreducelevel]->nextreduceable;
}
static void makereduceable(UINT level,OCTREE node)
{
node->nextreduceable = reducelist[level];
reducelist[level] = node;
}
/* reduzcamos el arbol, pues K+1>size */
static void reducetree(void)
{
OCTREE node;
UINT depth;
getreduceable(&node);
node->leaf = 1;
size = size - node->children + 1;
depth = node->level;
if (depth < reducelevel) {
reducelevel = depth;
leaflevel = reducelevel + 1;
}
}
static UCHAR insert_rgb[3];
/* para insertar cada color dentro del arbol */
static void inserttree(OCTREE *tree, UINT depth)
{
UINT branch;
if (*tree == NULL)
newandinit(tree,depth);
(*tree)->colorcount++;
(*tree)->rgbsum.r += insert_rgb[RED];
(*tree)->rgbsum.g += insert_rgb[GREEN];
(*tree)->rgbsum.b += insert_rgb[BLUE];
if ((*tree)->leaf == FALSE && depth < leaflevel) {
branch = TESTBIT(insert_rgb[RED],MAXDEPTH - depth) * 4 +
TESTBIT(insert_rgb[GREEN],MAXDEPTH - depth) * 2 +
TESTBIT(insert_rgb[BLUE],MAXDEPTH - depth);
if ((*tree)->next[branch] == NULL) {
(*tree)->children++;
if ((*tree)->children == 2)
makereduceable(depth,*tree);
}
inserttree(&((*tree)->next[branch]), depth + 1);
}
}
void lee(FILE *uno,double gamm) /* funci¢n que leer  la 1¦ vez el TGA */
{
union REGS regset;
struct SREGS sregset;
reducelevel = MAXDEPTH;
leaflevel = reducelevel + 1;
while (!feof(uno)) {
fread(&rgb_mio,3,1,uno);
insert_rgb[0]=rgb_mio[2]; // CUIDADO, valores de TGA tipo 2
insert_rgb[1]=rgb_mio[1]; // Estan BGR no RGB
insert_rgb[2]=rgb_mio[0];
inserttree(&tree, 0);
if (size > MAXCOLORS - 1) /* > K+1? (colores) */
reducetree();
}
calc_palette((unsigned int)0,gamm);
regset.x.ax=0x1012;
regset.x.bx=0;
regset.x.cx=256;
regset.x.dx=FP_OFF(palette);
sregset.es=FP_SEG(palette);
int86x(0x10,&regset,&regset,&sregset); /* interrupci¢n que carga y */
/* activa la paleta nueva */
}