00001 #include <stdio.h>
00002 #include <stdlib.h>
00003 #include <unistd.h>
00004 #include <string.h>
00005
00006 int vflag;
00007
00008 int
00009 RLED(void *src_raw, void *dest_raw, unsigned int src_size)
00010 {
00011 signed char *src = src_raw;
00012 signed char *dest = dest_raw;
00013 unsigned short used;
00014 short count, val;
00015 short i;
00016
00017 used = 0;
00018 while (used < src_size)
00019 {
00020 count = src[used++];
00021
00022 if (count < 0)
00023 {
00024 count = -(count - 1);
00025 val = src[used++];
00026
00027 if (vflag)
00028 printf("%6d: repeat %02x\n", count, val & 0xff);
00029
00030 for (i = 0; i < count; i++)
00031 *dest++ = val;
00032 }
00033 else
00034 {
00035 count++;
00036
00037 if (vflag)
00038 printf("%6d:", count);
00039
00040 for (i = 0; i < count; i++)
00041 {
00042 if (vflag)
00043 printf(" %02x", src[used] & 0xff);
00044 *dest++ = src[used++];
00045 }
00046
00047 if (vflag)
00048 printf("\n");
00049 }
00050 }
00051
00052 return ((void *) dest - (void *) dest_raw);
00053 }
00054
00055 void
00056 usage(void)
00057 {
00058 fprintf(stderr,
00059 "usage: mkmovie [-d output_dir] [-b output_basename] inputfile\n");
00060 exit(EXIT_FAILURE);
00061 }
00062
00063 struct frm
00064 {
00065 FILE *fin;
00066 int next_frame_chunks;
00067 int frame_idx;
00068 int nframes;
00069 int frame_rate;
00070 unsigned char pal[768];
00071 };
00072
00073 struct frm *
00074 frm_open(char *filename)
00075 {
00076 struct frm *frm;
00077 FILE *fin;
00078
00079 if ((fin = fopen(filename, "rb")) == NULL)
00080 return (NULL);
00081
00082 if ((frm = calloc(1, sizeof *frm)) == NULL)
00083 {
00084 fprintf(stderr, "out of memory\n");
00085 exit(EXIT_FAILURE);
00086 }
00087
00088 frm->fin = fin;
00089 frm->next_frame_chunks = 8;
00090 frm->frame_idx = 0;
00091
00092 return (frm);
00093 }
00094
00095 void
00096 frm_close(struct frm *frm)
00097 {
00098 if (frm)
00099 {
00100 if (frm->fin)
00101 fclose(frm->fin);
00102 free(frm);
00103 }
00104 }
00105
00106 int
00107 frm_get2(struct frm *frm, void *pixels_arg, void *map)
00108 {
00109 unsigned char raw[64 * 1024];
00110 unsigned char pbuf[64 * 1024];
00111 unsigned int n;
00112 int val0, val1;
00113 unsigned char *pixels;
00114
00115 n = frm->next_frame_chunks * 2048;
00116
00117 if (n == 0)
00118 {
00119 int count;
00120
00121 count = 0;
00122 while (getc(frm->fin) != EOF)
00123 count++;
00124
00125 return (0);
00126 }
00127
00128 if (n > sizeof raw)
00129 return (-1);
00130
00131 fread(raw, 1, n, frm->fin);
00132 val0 = raw[0] | (raw[1] << 8);
00133 val1 = raw[2];
00134
00135 if (frm->next_frame_chunks == 8)
00136 {
00137 if (frm->frame_idx == 0)
00138 {
00139 frm->nframes = val0;
00140 frm->frame_rate = raw[15998] | (raw[15999] << 8);
00141 if (frm->frame_rate == 0)
00142 frm->frame_rate = 8;
00143 memcpy(frm->pal + 384, raw + 16000, 384);
00144 }
00145 pixels = raw;
00146 }
00147 else
00148 {
00149 int compressed_size = val0;
00150
00151 RLED(raw + 3, pbuf, compressed_size);
00152 pixels = pbuf;
00153 }
00154
00155 memcpy(pixels_arg, pixels, 160 * 100);
00156 memcpy(map, frm->pal + 384, 384);
00157
00158 frm->next_frame_chunks = val1;
00159 frm->frame_idx++;
00160
00161 return (1);
00162 }
00163
00164 int
00165 main(int argc, char **argv)
00166 {
00167 FILE *movief;
00168 int c;
00169 char *filename;
00170 char *dirname = ".";
00171 char *basename = "frame";
00172 struct frm *frm;
00173 int rc;
00174 unsigned char pixels[64 * 1000], map[768];
00175 char outfname[100];
00176 int i, num;
00177 int pixel;
00178 unsigned char *up;
00179 int r, g, b;
00180
00181 while ((c = getopt(argc, argv, "d:b:")) != EOF)
00182 {
00183 switch (c)
00184 {
00185 case 'd':
00186 dirname = optarg;
00187 break;
00188 case 'b':
00189 basename = optarg;
00190 break;
00191 default:
00192 usage();
00193 }
00194 }
00195
00196 if (optind >= argc)
00197 usage();
00198
00199 filename = argv[optind++];
00200
00201 if (optind != argc)
00202 usage();
00203
00204 if ((frm = frm_open(filename)) == NULL)
00205 {
00206 fprintf(stderr, "can't open %s\n", filename);
00207 exit(EXIT_FAILURE);
00208 }
00209
00210 memset(map, 0, sizeof map);
00211 num = 0;
00212 while (1)
00213 {
00214 if ((rc = frm_get2(frm, pixels, &map[384])) < 0)
00215 {
00216 printf("error reading frame\n");
00217 exit(EXIT_FAILURE);
00218 }
00219
00220 if (rc == 0)
00221 break;
00222 sprintf(outfname, "%s/%s.%04d.ppm", dirname, basename, num++);
00223
00224 if ((movief = fopen(outfname, "wb")) == NULL)
00225 {
00226 fprintf(stderr, "can't create %s\n", outfname);
00227 exit(EXIT_FAILURE);
00228 }
00229
00230 fprintf(movief, "P6\n160 100\n255\n");
00231
00232 for (i = 0; i < 160 * 100; i++)
00233 {
00234 pixel = pixels[i];
00235 up = &map[pixel * 3];
00236
00237 r = up[0] * 4;
00238 g = up[1] * 4;
00239 b = up[2] * 4;
00240
00241 putc(r, movief);
00242 putc(g, movief);
00243 putc(b, movief);
00244 }
00245
00246 fclose(movief);
00247 }
00248 printf("%d frames written, framerate %dfps\n", num, frm->frame_rate);
00249 frm_close(frm);
00250 return (EXIT_SUCCESS);
00251 }