home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 9 / CD_ASCQ_09_1193.iso / news / 4441 / yuvpak / yuvunpak.c < prev    next >
C/C++ Source or Header  |  1993-01-30  |  7KB  |  198 lines

  1. /*
  2. ** Copyright (C) 1992 WD Young, P.O. Box 632871, Nacogdoches TX 75963-2871
  3. **
  4. ** This file is distributed under the terms listed in the document
  5. ** "copying.wy", available from WD Young at the address above.
  6. ** A copy of "copying.wy" should accompany this file; if not, a copy
  7. ** should be available from where this file was obtained.  This file
  8. ** may not be distributed without a verbatim copy of "copying.wy".
  9. **
  10. ** This file is distributed WITHOUT ANY WARRANTY; without even the implied
  11. ** warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  12. */
  13.  
  14. /* This program decodes .IFS files into .KRD files */
  15.  
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include <graphics.h>
  19. #include <math.h>
  20. #include <string.h>
  21. #define range domain
  22. #define max_scale 1.2
  23. int main(int argc, char **argv)
  24. {
  25.    unsigned char domain [256][256][3];
  26.    FILE *in, *krd, *out;
  27.    char *inf, *krdf,level, test, dense = 64, sfactor = 1;
  28.    unsigned char r, g, b;
  29.    int xsize=256, ysize=256;
  30.    int x, y, dx, dy, rx, ry, tsx, tsy, qx, qy;
  31.    int ii[64][64], ddxx[64][64], ddyy[64][64];
  32.    int transx[64][64], transy[64][64], yuv;
  33.    float ss[64][64], oo[64][64], z;
  34.    int level_table[64][64], patchsize[2] = {8, 4}, PS, PS1, number_ifses;
  35.    int ix, iy, iddxx, iddyy, n, i, nflips=8, niterations, nummaps[3];
  36.    float rms,s, o, yf, uf, vf, rf, gf, bf;
  37.    int f11[] = {1, 0, -1, 0, 1, 0, -1, 0}, f12[] = {0, 1, 0, -1, 0, -1, 0, 1};
  38.    int f21[] = {0, -1, 0, 1, 0, -1, 0, 1}, f22[] = {1, 0, -1, 0, -1, 0, 1, 0};
  39.    char tgaheader[] = {0,0, 2,0, 0,0, 0,0, 0,0, 0,0, 0,1, 0,1, 24,32};
  40.    struct trans_out {
  41.       unsigned char dx;
  42.       unsigned char dy;
  43.       signed char scale : 7;
  44.       short int offset : 7;
  45.       unsigned short int flip : 3;
  46.       unsigned short int size : 1;
  47.       } transout[1];
  48.  
  49.     struct header_t {   /* "should" be a 12 byte header... we'll see */
  50.       long time;        /* 4 bytes for compression time in seconds */
  51.       short rms;        /* 2 bytes for 100.*rms value */
  52.       short add1;       /* 2 bytes to be added later... room for growth */
  53.       long add2;        /* 4 bytes to be added later... room for growth */
  54.       } header[1];
  55.  
  56.  
  57.    if ((argc < 2)||(argc > 3)) {
  58.       printf("\nusage: yuvunpak infile.ifs outfile.krd\n\n");
  59.       printf("YUVUNPAK Version 2.0, Copyright (C) 1993, WD Young\n");
  60.       printf("YUVUNPAK comes with ABSOLUTELY NO WARRANTY\n");
  61.       printf("Please see files 'copying.wy' and 'copying' for details\n");
  62.       printf("If these files are missing,\n");
  63.       printf("write: WD Young, P.O. Box 632871, Nacogdoches TX 75963-2871\n");
  64.       return 1;
  65.       }
  66.    niterations = 10;
  67.    inf = argv[1]; krdf = argv[2];
  68.    
  69.    if ((in = fopen(inf, "rb")) == NULL) {
  70.       fprintf(stderr, "Cannot open input file.\n");
  71.       return 1;
  72.       }
  73.    if ((krd = fopen(krdf, "wb")) == NULL) {
  74.       fprintf(stderr, "Cannot open output file.\n");
  75.       return 1;
  76.       }
  77.  
  78.    GrSetMode(GR_default_graphics);
  79.    for (y = 0; y < 64; y++)
  80.       GrSetColor(y,4*y,4*y,4*y);
  81.    for (y = 64; y < 256; y++)
  82.       GrSetColor(y,0,y/2,y);
  83.  
  84.    for (yuv = 0; yuv < 3; yuv++) {
  85.    if (yuv >= 1) {
  86.         dense = 16;
  87.         patchsize[0] = 32;
  88.         patchsize[1] = 16;
  89.         sfactor = 4;
  90.    }
  91.    if (yuv == 2) fread(header, sizeof(struct header_t), 1, in);
  92.    number_ifses = 0;
  93.    for (ry = 0; ry < dense; ry+=2)
  94.    for (rx = 0; rx < dense; rx+=2)
  95.       {
  96.       fread(transout, sizeof(struct trans_out), 1, in);
  97.       level = transout[0].size;
  98.       PS1 = patchsize[level] - 1;
  99.       if (level == 0) number_ifses++;
  100.       else number_ifses+=4;
  101.       for (y = ry; y < ry+2; y++)
  102.       for (x = rx; x < rx+2; x++) {
  103.           level_table[y][x] = level;
  104.           if (level == 1
  105.            && (x != rx || y != ry)) fread(transout, sizeof(struct trans_out), 1, in);
  106.           ddxx[y][x] = dx = sfactor*(int)transout[0].dx;
  107.           ddyy[y][x] = dy = sfactor*(int)transout[0].dy;
  108.           ii[y][x] = i = transout[0].flip;
  109.           ss[y][x] = max_scale*(((float)transout[0].scale)/63.);
  110.           oo[y][x] = transout[0].offset<<3;
  111.           transx[y][x] = 2*patchsize[1]*x + PS1 - (f11[i]*(dx+PS1) + f12[i]*(dy+PS1));
  112.           transy[y][x] = 2*patchsize[1]*y + PS1 - (f21[i]*(dx+PS1) + f22[i]*(dy+PS1));
  113.           }
  114.       }
  115.    nummaps[yuv] = number_ifses;
  116.    for (n = 0; n < niterations; n++)
  117.    {
  118. /* Run through all non-overlapping NxN "R" blocks in the image  */
  119.     for (ry = 0; ry < dense; ry++)
  120.         {
  121.         for (rx = 0; rx < dense; rx++)
  122.             {
  123.             level = level_table[ry][rx];
  124.             if (level == 0
  125.              && (((rx % 2) !=0) || ((ry % 2) != 0))) continue; /* already covered in 8X8 */
  126.             PS = patchsize[level];
  127.             s = ss [ry] [rx];
  128.             o = oo [ry] [rx];
  129.             i = ii [ry] [rx];
  130.             tsx = transx [ry] [rx];
  131.             tsy = transy [ry] [rx];
  132.             iddyy = ddyy [ry] [rx];
  133.             iddxx = ddxx [ry] [rx];
  134. /*************************************************************************/
  135. /*                Average & Transform the 256 2x2 "pixels"               */
  136. /*************************************************************************/
  137.             for (y = 0; y < 2*PS; y+=2)
  138.             for (x = 0; x < 2*PS; x+=2)
  139.                 {
  140.                 dy = iddyy + y;
  141.                 dx = iddxx + x;
  142.                 z = (float)((domain[dy  ][dx  ][yuv]
  143.                            + domain[dy  ][dx+1][yuv]
  144.                            + domain[dy+1][dx  ][yuv]
  145.                            + domain[dy+1][dx+1][yuv]) >> 2);
  146.  
  147.                 ix = (f11[i]*dx + f12[i]*dy + tsx) >> 1;
  148.                 iy = (f21[i]*dx + f22[i]*dy + tsy) >> 1;
  149.                 z = s*z + o;
  150.                 if (z > 255.) z = 255.; else if (z < 0.) z = 0.;
  151.                 range[iy][ix][yuv] = (unsigned char)z;
  152.                 GrPlot(ix,iy,((int)z)>>2);
  153.                 }
  154.             }
  155.         }
  156.    }
  157.  
  158.    }
  159.    for (y = 0; y < 18; y++)
  160.     fputc(tgaheader[y],krd);
  161.    for (y = 0; y < 256; y++)
  162.    for (x = 0; x < 256; x++) {
  163.     yf = (float)range[y][x][0];
  164.     uf = (float)range[y][x][1];
  165.     vf = (float)range[y][x][2];
  166.     uf =  316.*uf/255. - 158.;
  167.     vf =  224.*vf/255. - 112.;
  168.     rf =  (yf + 1.131*uf + 0.00698215*vf);
  169.     if (rf < 0.) r = 0;
  170.     else
  171.     if (rf > 255.) r = 255;
  172.     else r = (unsigned char)rf;
  173.     gf =  (yf - 0.576*uf - 0.3809*vf);
  174.     if (gf < 0.) g = 0;
  175.     else
  176.     if (gf > 255.) g = 255;
  177.     else g = (unsigned char)gf;
  178.     bf =  (yf + 0.005818*uf + 2.024*vf);
  179.     if (bf < 0.) b = 0;
  180.     else
  181.     if (bf > 255.) b = 255;
  182.     else b = (unsigned char)bf;
  183.     fputc(b,krd);
  184.     fputc(g,krd);
  185.     fputc(r,krd);
  186.    }
  187.    fclose(in);
  188.    fclose(krd);
  189.    GrSetMode(GR_default_text);
  190.    printf("ymap: %4i umap: %4i vmap: %4i\n",nummaps[0],nummaps[1],nummaps[2]);
  191.    printf("compression ratio: %4.2f\n",192.*1024./((float)(nummaps[0]+nummaps[1]+nummaps[2])*4.25));
  192.    printf("compression time: %5i\n",header[0].time);
  193.    printf("pack rms: %4.1f\n",(((float)header[0].rms)/100.));
  194.  
  195. /* All done. Whew... */
  196.    return 0;
  197. }
  198.