mirror of
https://github.com/ondra-novak/gates_of_skeldal.git
synced 2025-07-19 12:44:55 -04:00
172 lines
3.5 KiB
C
172 lines
3.5 KiB
C
#include <libs/types.h>
|
|
#include <stdio.h>
|
|
#include <math.h>
|
|
#include "jpegmgif.h"
|
|
|
|
typedef short C_MATICE[4][4];
|
|
typedef float R_MATICE[4][4];
|
|
/*
|
|
C_MATICE quant=
|
|
{
|
|
{16,10,24,51},
|
|
{14,16,40,69},
|
|
{18,37,68,103},
|
|
{49,78,103,120},
|
|
};
|
|
*/
|
|
C_MATICE quant=
|
|
{
|
|
{2,2,4,24},
|
|
{2,4,8,26},
|
|
{4,8,50,80},
|
|
{8,30,80,88},
|
|
};
|
|
|
|
char xlat_table[256];
|
|
|
|
char code_tab[][2]=
|
|
{
|
|
{0,0},{1,0},{0,1},{0,2},{1,1},{2,0},{3,0},{2,1},{1,2},{0,3},{1,3},{2,2},{3,1},
|
|
{3,2},{2,3},{3,3}
|
|
};
|
|
|
|
int cos_tab[16][16][256];
|
|
short cuv_tab[16];
|
|
|
|
TBOX *rbbox;
|
|
TBOX *gbbox;
|
|
TBOX *ibox;
|
|
|
|
#define CUV (1/1.414)
|
|
#define PI 3.14159265
|
|
#define C(u) (u==0?CUV:1)
|
|
#define FIXED 512
|
|
#define SCAN_LINE 640
|
|
|
|
int line_skip=4*640;
|
|
|
|
void unpack_block(void *source,void *target,int size);
|
|
#pragma aux unpack_block parm [esi][edi][ecx] modify [ebx edx eax]
|
|
void konv_iyg_hicolor(void *ii,void *rb,void *gb,void *screen);
|
|
#pragma aux konv_iyg_hicolor parm[esi][edx][ebx][edi] modify [eax ecx]
|
|
|
|
void create_cos_tab()
|
|
{
|
|
char u,v,i,k,x,y;
|
|
int j,tst;
|
|
signed char cc,*c;
|
|
|
|
for(j=0;j<256;j++)
|
|
for(i=0;i<16;i++)
|
|
for(k=0;k<16;k++)
|
|
{
|
|
u=code_tab[i][0];
|
|
v=code_tab[i][1];
|
|
x=k & 3;
|
|
y=k >> 2;
|
|
cc=j & 0xff;
|
|
tst=cos_tab[k][i][j]=(int)(quant[u][v]*cc*C(u)*C(v)*cos((2*x+1)*u*PI/8.0)*cos((2*y+1)*v*PI/8.0)*FIXED);
|
|
}
|
|
for(i=0;i<16;i++)
|
|
{
|
|
u=code_tab[i][0];
|
|
v=code_tab[i][1];
|
|
cuv_tab[i]=(u==0)+(v==0);
|
|
}
|
|
c=xlat_table;
|
|
for(j=0;j<256;j++) if (j>127) *c++=0;else if(j>31) *c++=31;else *c++=j;
|
|
}
|
|
|
|
short zaokrouhlit(float f)
|
|
{
|
|
if (f>0) return (short)(f+0.5);
|
|
if (f<0) return (short)(f-0.5);
|
|
return 0;
|
|
}
|
|
|
|
void Dopredna_transformace(C_MATICE data,C_MATICE koef)
|
|
{
|
|
char u,v,x,y;
|
|
float msum;
|
|
|
|
for(u=0;u<4;u++)
|
|
for(v=0;v<4;v++)
|
|
{
|
|
msum=0;
|
|
for(x=0;x<4;x++)
|
|
for(y=0;y<4;y++)
|
|
msum+=data[x][y]*cos((2*x+1)*u*PI/8.0)*cos((2*y+1)*v*PI/8.0);
|
|
msum*=C(u)*C(v)/4.0;
|
|
koef[u][v]=zaokrouhlit(msum/quant[u][v]);
|
|
}
|
|
}
|
|
|
|
void Kodovani(C_MATICE data,char *out)
|
|
{
|
|
int i;
|
|
for(i=0;i<16;i++)
|
|
{
|
|
*out++=(char)(data[code_tab[i][0]][code_tab[i][1]]);
|
|
}
|
|
}
|
|
|
|
int string_size(char *data)
|
|
{
|
|
int i;
|
|
i=16;
|
|
do
|
|
i--;
|
|
while (i && !data[i]);
|
|
return i+1;
|
|
}
|
|
|
|
int transformace(void *screen_data,signed char *trans_data,int nextline,int box_place)
|
|
{
|
|
C_MATICE icm,rbcm,gbcm;
|
|
C_MATICE irm,rbrm,gbrm;
|
|
short i,r,g,a=0;
|
|
signed char *p;
|
|
signed char *ii,*rb,*gb;
|
|
int x,y;
|
|
char *tr=trans_data;
|
|
|
|
ii=ibox[box_place];
|
|
rb=rbbox[box_place];
|
|
gb=gbbox[box_place];
|
|
|
|
for(y=0;y<4;y++)
|
|
{
|
|
p=(char *)screen_data+nextline*3*y;
|
|
for(x=0;x<4;x++,a++)
|
|
{
|
|
i=(p[2]+p[1]+p[0]);
|
|
r=(i-p[0]);
|
|
g=(i-p[1]);
|
|
icm[x][y]=i-ii[a];
|
|
rbcm[x][y]=r-rb[a];
|
|
gbcm[x][y]=g-gb[a];
|
|
p+=3;
|
|
}
|
|
}
|
|
Dopredna_transformace(icm,irm);
|
|
Dopredna_transformace(rbcm,rbrm);
|
|
Dopredna_transformace(gbcm,gbrm);
|
|
Kodovani(irm,trans_data+1);trans_data+=1+(*trans_data=string_size(trans_data+1));
|
|
Kodovani(rbrm,trans_data+1);trans_data+=1+(*trans_data=string_size(trans_data+1));
|
|
Kodovani(gbrm,trans_data+1);trans_data+=1+(*trans_data=string_size(trans_data+1));
|
|
return trans_data-tr;
|
|
}
|
|
|
|
void zpetna_transformace(char **data,void *screen,int box_place)
|
|
{
|
|
TBOX *ii,*rb,*gb;
|
|
char *dd=*data;
|
|
unpack_block(dd+1,ii=ibox+box_place,*dd);dd+=dd[0]+1;
|
|
unpack_block(dd+1,rb=gbbox+box_place,*dd);dd+=dd[0]+1;
|
|
unpack_block(dd+1,gb=rbbox+box_place,*dd);dd+=dd[0]+1;
|
|
*data=dd;
|
|
konv_iyg_hicolor(ii,rb,gb,screen);
|
|
}
|
|
|
|
|
|
|