utils/mkmovie.c

Go to the documentation of this file.
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         // printf ("trailing bytes %d\n", count);
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 }

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