home *** CD-ROM | disk | FTP | other *** search
-
- /* This module converts the DOOM raw image format to PPM image format
-
- (PPM, mainly because I know its format)
-
- */
-
- #include <stdio.h>
- #include <assert.h>
- #include "doomdefs.h"
- #include "directory.h"
-
-
- struct raw_header {
- two_byte width; /* Picture width */
- two_byte height; /* Picture height */
- two_byte l_offset; /* Left offset from center (unused?) */
- two_byte t_offset; /* Top offset from center (unused?) */
- };
-
- struct color {
- unsigned char red;
- unsigned char green;
- unsigned char blue;
- } colormap[256];
-
- /* The background color for the pictures */
- struct color cyan = { 0, 255, 255 };
-
- int load_colormap(int fd) {
- struct dir_entry entry;
-
- /* Set the fd to the start of the directory entries */
- if ( set_directory(fd) < 0 )
- return(-1);
-
- /* Now cycle through the entries, looking for PLAYMAP */
- if ( get_entry(fd, "PLAYPAL", &entry) < 0 )
- return(-1);
-
- /* Go to the entry and retrieve the first colormap (colormap 0) */
- if ( lseek(fd, entry.res_start, SEEK_SET) < 0 )
- return(-1);
- if (read(fd, (char *)&colormap, sizeof(colormap)) != sizeof(colormap))
- return(-1);
-
- return(0);
- }
-
- int convert_rawpic(int fd, char *name)
- {
- struct dir_entry entry;
- struct raw_header header;
- struct color *matrix;
- four_byte *columns;
- unsigned char post_row, num_pixels, pixel;
- char outfile[BUFSIZ];
- FILE *output;
- int i, j, l, index;
-
- /* Load the default colormap first */
- if ( load_colormap(fd) < 0 ) {
- fprintf(stderr, "Couldn't load color map from doom.wad\n");
- return(-1);
- }
-
- /* Set the fd to the start of the directory entries */
- if ( set_directory(fd) < 0 ) {
- fprintf(stderr, "Can't find start of directories.\n");
- return(-1);
- }
-
- /* Now cycle through the entries, looking for the picture */
- if ( get_entry(fd, name, &entry) < 0 ) {
- fprintf(stderr, "Couldn't find directory entry for %s\n", name);
- return(-1);
- }
-
- /* Go to the entry and retrieve the picture */
- if ( lseek(fd, entry.res_start, SEEK_SET) < 0 ) {
- perror("lseek()");
- return(-1);
- }
- if (read(fd, (char *)&header, sizeof(header)) != sizeof(header)) {
- perror("header read error");
- return(-1);
- }
- /* Print out the header for now */
- printf("Picture size: %dx%d (left offset=%d, top offset=%d)\n",
- header.width, header.height, header.l_offset, header.t_offset);
-
- /* Allocate memory for the picture */
- if ( (matrix=(struct color *)malloc(
- sizeof(struct color)*(header.width*header.height))) == NULL ) {
- perror("malloc(matrix)");
- return(-1);
- }
- if ( (columns=(four_byte *)malloc(header.width*4)) == NULL ) {
- perror("malloc(columns)");
- return(-1);
- }
-
- /* Set the default color to cyan */
- for ( i=0; i<header.height; ++i )
- for ( j=0; j<header.width; ++j )
- matrix[(i*header.width)+j] = cyan;
-
- /* Convert the raw picture format into the pixel matrix */
- /* Get all the columns pointers */
- if ( read(fd, (char *)columns, header.width*4) != (header.width*4) ) {
- perror("read(columns");
- return(-1);
- }
- /* I tried using the offsets in the header, but they didn't seem
- to be relevant. Thus, I ignore them.
- */
- for ( i=0; i<header.width; ++i ) {
- /* Each column is stored as a series of posts */
- if ( lseek(fd, entry.res_start+columns[i], SEEK_SET) < 0 ) {
- perror("lseek(columns)");
- return(-1);
- }
- for ( ; ; ) {
- /* The first byte is the starting row of the post */
- if ( read(fd, &post_row, 1) != 1 ) {
- perror("read()");
- return(-1);
- }
- if ( post_row == 255 ) /* End of column marker */
- break;
- /* The second byte is the number of pixels in the post */
- if ( read(fd, &num_pixels, 1) != 1 ) {
- perror("read()");
- return(-1);
- }
- /* Skip first and last pixel bytes */
- (void) read(fd, &pixel, 1);
- for ( j=0; j<num_pixels; ++j ) {
- if ( read(fd, &pixel, 1) != 1 ) {
- perror("read()");
- return(-1);
- }
- index=((post_row*header.width)+i);
- assert(index > 0);
- matrix[index] = colormap[pixel];
- ++post_row;
- }
- (void) read(fd, &pixel, 1);
- }
- }
-
- /* Make sure we can write the output file */
- sprintf(outfile, "%s.ppm", name);
- if ( (output=fopen(outfile, "w")) == NULL ) {
- fprintf(stderr, "Can't open %s for writing.\n", outfile);
- return(-1);
- }
- /* Write the output file */
- fprintf(output, "P3\n"); /* PPM Magic cookie */
- fprintf(output, "# %s\n", outfile);
- fprintf(output, "%d %d\n", header.width, header.height);
- fprintf(output, "255\n"); /* The maximum color value */
- /* Now the matrix itself */
- for ( i=0; i<header.height; ++i ) {
- fprintf(output, "# row %d\n", i);
- for ( j=0, l=0; j<header.width; ++j ) {
- index = ((i*header.width)+j);
- sprintf(outfile, "%d %d %d ", matrix[index].red,
- matrix[index].green, matrix[index].blue);
-
- /* The line can be no longer than 70 chars */
- l += strlen(outfile);
- if ( l > 70 ) {
- fprintf(output, "\n");
- l = strlen(outfile);
- }
- fprintf(output, "%s", outfile);
- }
- fprintf(output, "\n");
- }
- fclose(output);
-
- /* Free malloc()'d data here. It is not freed on errors */
- (void) free(matrix);
- (void) free(columns);
-
- /* Done! */
- return(0);
- }
-