/* ** 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 #include #include #include #include #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; }