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;
00040 src_i++;
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