decode.c

Go to the documentation of this file.
00001 #include <stdio.h>
00002 #include <stdlib.h>
00003 #include <unistd.h>
00004 #include <memory.h>
00005 
00006 char inbuf[1000 * 1000];
00007 char outbuf[1000 * 1000];
00008 
00009 int insize;
00010 int outsize;
00011 
00012 int vflag;
00013 
00014 long
00015 RLEC (char *src, char *dest, unsigned int src_size)
00016 {
00017     short src_i, dest_i, limit;
00018     short togo;
00019     
00020     dest_i = 0;
00021     src_i = 0;
00022     while ((togo = src_size - src_i) > 0) {
00023         int thistime;
00024 
00025         limit = togo - 1;
00026         if (limit >= 128)
00027             limit = 128;
00028 
00029         thistime = 0;
00030         while (thistime < limit && src[src_i] != src[src_i+1]) {
00031             thistime++;
00032             src_i++;
00033         }
00034         if (thistime) {
00035             dest[dest_i++] = (thistime-1);
00036             memcpy (&dest[dest_i], &src[src_i-thistime], thistime);
00037             dest_i += thistime;
00038         } else {
00039             thistime = 2;   /* at least 2 chars to be repeated */
00040             src_i++; /* advance pointer beyond the first match*/
00041             while (thistime < limit && src[src_i] == src[src_i+1]){
00042                 thistime++;
00043                 src_i++;
00044             }
00045             dest[dest_i++] = (-thistime+1);
00046             dest[dest_i++] = src[src_i++];
00047         }
00048     }
00049     return (dest_i);
00050 }
00051 
00052 
00053 int
00054 RLED (void *src_raw, void *dest_raw, unsigned int src_size)
00055 {
00056     signed char *src = src_raw;
00057     signed char *dest = dest_raw;
00058     unsigned short used;
00059     short count, val;
00060     short i;
00061 
00062     used = 0;
00063     while (used < src_size) {
00064         count = src[used++];
00065         
00066         if (count < 0) {
00067             count = -(count - 1);
00068             val = src[used++];
00069             
00070             if (vflag)
00071                 printf ("%6d: repeat %02x\n", count, val&0xff);
00072 
00073             for (i = 0; i < count; i++)
00074                 *dest++ = val;
00075         } else {
00076             count++;
00077 
00078             if (vflag)
00079                 printf ("%6d:", count);
00080 
00081             for (i = 0; i < count; i++) {
00082                 if (vflag)
00083                     printf (" %02x", src[used] & 0xff);
00084                 *dest++ = src[used++];
00085             }
00086 
00087             if (vflag)
00088                 printf ("\n");
00089         }
00090     }
00091 
00092     return ((void *)dest - (void *)dest_raw);
00093 }
00094 
00095 int
00096 RLED2 (char *src, char *dest, unsigned int src_size)
00097 {
00098     short ax, bx, cx;
00099     char const *si;
00100     char *di;
00101 
00102     di = dest;
00103     si = src;
00104     cx = 0;
00105     bx = src_size;
00106 
00107 loa:
00108     ax = *si++ & 0xff;
00109     bx--;
00110     if (ax & 0x80)
00111         goto repeat;
00112 
00113     ax = (ax + 1) & 0xff;
00114     cx = ax;
00115 
00116     do
00117         *di++ = *si++;
00118     while (--cx);
00119 
00120     bx -= ax;
00121 
00122     if (bx > 0)
00123         goto loa;
00124     goto bot;
00125 
00126 repeat:
00127     ax = -ax;
00128     ax++;
00129     cx = ax & 0xff;
00130 
00131     ax = *si++ & 0xff;
00132 
00133 lob:
00134     *di++ = ax;
00135     if (--cx)
00136         goto lob;
00137     bx--;
00138     if (bx > 0)
00139         goto loa;
00140 
00141 bot: 
00142     return (di - dest);
00143 }
00144 
00145 void
00146 usage (void)
00147 {
00148     fprintf (stderr, "usage: decode file\n");
00149     exit (1);
00150 }
00151 
00152 int width, height;
00153 
00154 int
00155 main (int argc, char **argv)
00156 {
00157     int c;
00158     char *filename;
00159     FILE *f;
00160     FILE *outf;
00161 
00162     while ((c = getopt (argc, argv, "vw:h:")) != EOF) {
00163         switch (c) {
00164         case 'w':
00165             width = atoi (optarg);
00166             break;
00167         case 'h':
00168             height = atoi (optarg);
00169             break;
00170         case 'v':
00171             vflag = 1;
00172             break;
00173         default:
00174             usage ();
00175         }
00176     }
00177 
00178     if (optind >= argc)
00179         usage ();
00180 
00181     filename = argv[optind++];
00182 
00183     if (optind != argc)
00184         usage ();
00185 
00186     if ((f = fopen (filename, "rb")) == NULL) {
00187         fprintf (stderr, "can't open %s\n", filename);
00188         exit (1);
00189     }
00190 
00191     fread (inbuf, 1, 80, f);
00192     insize = fread (inbuf, 1, sizeof inbuf, f);
00193 
00194     printf ("input size %d\n", insize);
00195 
00196     outsize = RLED (inbuf, outbuf, insize);
00197 
00198     printf ("output size %d\n", outsize);
00199 
00200     if (width && height) {
00201         if ((outf = fopen ("d.pgm", "wb")) == NULL) {
00202             fprintf (stderr, "can't create d.pgm\n");
00203             exit (1);
00204         }
00205         fprintf (outf, "P5\n%d %d\n255\n", width, height);
00206         fwrite (outbuf, 1, width * height, outf);
00207         fclose (outf);
00208     }
00209 
00210     return (0);
00211 }
00212 

Generated on Fri Sep 28 00:35:45 2007 for raceintospace by  doxygen 1.5.3