home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DP Tool Club 9
/
CD_ASCQ_09_1193.iso
/
news
/
4441
/
yuvpak
/
yuvunpak.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-01-30
|
7KB
|
198 lines
/*
** Copyright (C) 1992 WD Young, P.O. Box 632871, Nacogdoches TX 75963-2871
**
** This file is distributed under the terms listed in the document
** "copying.wy", available from WD Young at the address above.
** A copy of "copying.wy" should accompany this file; if not, a copy
** should be available from where this file was obtained. This file
** may not be distributed without a verbatim copy of "copying.wy".
**
** This file is distributed WITHOUT ANY WARRANTY; without even the implied
** warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
/* This program decodes .IFS files into .KRD files */
#include <stdio.h>
#include <stdlib.h>
#include <graphics.h>
#include <math.h>
#include <string.h>
#define range domain
#define max_scale 1.2
int main(int argc, char **argv)
{
unsigned char domain [256][256][3];
FILE *in, *krd, *out;
char *inf, *krdf,level, test, dense = 64, sfactor = 1;
unsigned char r, g, b;
int xsize=256, ysize=256;
int x, y, dx, dy, rx, ry, tsx, tsy, qx, qy;
int ii[64][64], ddxx[64][64], ddyy[64][64];
int transx[64][64], transy[64][64], yuv;
float ss[64][64], oo[64][64], z;
int level_table[64][64], patchsize[2] = {8, 4}, PS, PS1, number_ifses;
int ix, iy, iddxx, iddyy, n, i, nflips=8, niterations, nummaps[3];
float rms,s, o, yf, uf, vf, rf, gf, bf;
int f11[] = {1, 0, -1, 0, 1, 0, -1, 0}, f12[] = {0, 1, 0, -1, 0, -1, 0, 1};
int f21[] = {0, -1, 0, 1, 0, -1, 0, 1}, f22[] = {1, 0, -1, 0, -1, 0, 1, 0};
char tgaheader[] = {0,0, 2,0, 0,0, 0,0, 0,0, 0,0, 0,1, 0,1, 24,32};
struct trans_out {
unsigned char dx;
unsigned char dy;
signed char scale : 7;
short int offset : 7;
unsigned short int flip : 3;
unsigned short int size : 1;
} transout[1];
struct header_t { /* "should" be a 12 byte header... we'll see */
long time; /* 4 bytes for compression time in seconds */
short rms; /* 2 bytes for 100.*rms value */
short add1; /* 2 bytes to be added later... room for growth */
long add2; /* 4 bytes to be added later... room for growth */
} header[1];
if ((argc < 2)||(argc > 3)) {
printf("\nusage: yuvunpak infile.ifs outfile.krd\n\n");
printf("YUVUNPAK Version 2.0, Copyright (C) 1993, WD Young\n");
printf("YUVUNPAK comes with ABSOLUTELY NO WARRANTY\n");
printf("Please see files 'copying.wy' and 'copying' for details\n");
printf("If these files are missing,\n");
printf("write: WD Young, P.O. Box 632871, Nacogdoches TX 75963-2871\n");
return 1;
}
niterations = 10;
inf = argv[1]; krdf = argv[2];
if ((in = fopen(inf, "rb")) == NULL) {
fprintf(stderr, "Cannot open input file.\n");
return 1;
}
if ((krd = fopen(krdf, "wb")) == NULL) {
fprintf(stderr, "Cannot open output file.\n");
return 1;
}
GrSetMode(GR_default_graphics);
for (y = 0; y < 64; y++)
GrSetColor(y,4*y,4*y,4*y);
for (y = 64; y < 256; y++)
GrSetColor(y,0,y/2,y);
for (yuv = 0; yuv < 3; yuv++) {
if (yuv >= 1) {
dense = 16;
patchsize[0] = 32;
patchsize[1] = 16;
sfactor = 4;
}
if (yuv == 2) fread(header, sizeof(struct header_t), 1, in);
number_ifses = 0;
for (ry = 0; ry < dense; ry+=2)
for (rx = 0; rx < dense; rx+=2)
{
fread(transout, sizeof(struct trans_out), 1, in);
level = transout[0].size;
PS1 = patchsize[level] - 1;
if (level == 0) number_ifses++;
else number_ifses+=4;
for (y = ry; y < ry+2; y++)
for (x = rx; x < rx+2; x++) {
level_table[y][x] = level;
if (level == 1
&& (x != rx || y != ry)) fread(transout, sizeof(struct trans_out), 1, in);
ddxx[y][x] = dx = sfactor*(int)transout[0].dx;
ddyy[y][x] = dy = sfactor*(int)transout[0].dy;
ii[y][x] = i = transout[0].flip;
ss[y][x] = max_scale*(((float)transout[0].scale)/63.);
oo[y][x] = transout[0].offset<<3;
transx[y][x] = 2*patchsize[1]*x + PS1 - (f11[i]*(dx+PS1) + f12[i]*(dy+PS1));
transy[y][x] = 2*patchsize[1]*y + PS1 - (f21[i]*(dx+PS1) + f22[i]*(dy+PS1));
}
}
nummaps[yuv] = number_ifses;
for (n = 0; n < niterations; n++)
{
/* Run through all non-overlapping NxN "R" blocks in the image */
for (ry = 0; ry < dense; ry++)
{
for (rx = 0; rx < dense; rx++)
{
level = level_table[ry][rx];
if (level == 0
&& (((rx % 2) !=0) || ((ry % 2) != 0))) continue; /* already covered in 8X8 */
PS = patchsize[level];
s = ss [ry] [rx];
o = oo [ry] [rx];
i = ii [ry] [rx];
tsx = transx [ry] [rx];
tsy = transy [ry] [rx];
iddyy = ddyy [ry] [rx];
iddxx = ddxx [ry] [rx];
/*************************************************************************/
/* Average & Transform the 256 2x2 "pixels" */
/*************************************************************************/
for (y = 0; y < 2*PS; y+=2)
for (x = 0; x < 2*PS; x+=2)
{
dy = iddyy + y;
dx = iddxx + x;
z = (float)((domain[dy ][dx ][yuv]
+ domain[dy ][dx+1][yuv]
+ domain[dy+1][dx ][yuv]
+ domain[dy+1][dx+1][yuv]) >> 2);
ix = (f11[i]*dx + f12[i]*dy + tsx) >> 1;
iy = (f21[i]*dx + f22[i]*dy + tsy) >> 1;
z = s*z + o;
if (z > 255.) z = 255.; else if (z < 0.) z = 0.;
range[iy][ix][yuv] = (unsigned char)z;
GrPlot(ix,iy,((int)z)>>2);
}
}
}
}
}
for (y = 0; y < 18; y++)
fputc(tgaheader[y],krd);
for (y = 0; y < 256; y++)
for (x = 0; x < 256; x++) {
yf = (float)range[y][x][0];
uf = (float)range[y][x][1];
vf = (float)range[y][x][2];
uf = 316.*uf/255. - 158.;
vf = 224.*vf/255. - 112.;
rf = (yf + 1.131*uf + 0.00698215*vf);
if (rf < 0.) r = 0;
else
if (rf > 255.) r = 255;
else r = (unsigned char)rf;
gf = (yf - 0.576*uf - 0.3809*vf);
if (gf < 0.) g = 0;
else
if (gf > 255.) g = 255;
else g = (unsigned char)gf;
bf = (yf + 0.005818*uf + 2.024*vf);
if (bf < 0.) b = 0;
else
if (bf > 255.) b = 255;
else b = (unsigned char)bf;
fputc(b,krd);
fputc(g,krd);
fputc(r,krd);
}
fclose(in);
fclose(krd);
GrSetMode(GR_default_text);
printf("ymap: %4i umap: %4i vmap: %4i\n",nummaps[0],nummaps[1],nummaps[2]);
printf("compression ratio: %4.2f\n",192.*1024./((float)(nummaps[0]+nummaps[1]+nummaps[2])*4.25));
printf("compression time: %5i\n",header[0].time);
printf("pack rms: %4.1f\n",(((float)header[0].rms)/100.));
/* All done. Whew... */
return 0;
}