executor/src/gensplash.c

384 lines
8.5 KiB
C

/* Copyright 1995 by Abacus Research and
* Development, Inc. All rights reserved.
*/
#if !defined (OMIT_RCSID_STRINGS)
char ROMlib_rcsid_gensplash[] =
"$Id: gensplash.c 63 2004-12-24 18:19:43Z ctm $";
#endif
#include "rsys/common.h"
#include <stdarg.h>
#include "rsys/splash.h"
int bpp, log2_bpp;
struct splash_screen_color color_buf[256];
int alloc_pixel;
boolean_t pixmap_p;
void
_errno_fatal (const char *file, int line, const char *fn,
const char *fmt, ...)
{
va_list ap;
int save_errno = errno;
fprintf (stderr, "%s:%d; fatal error in `%s': ",
file, line, fn);
va_start (ap, fmt);
vfprintf (stderr, fmt, ap);
va_end (ap);
fprintf (stderr, ": %s\n", strerror (save_errno));
exit (-1);
}
void
init_color_buf (void)
{
memset (color_buf, '\377', sizeof *color_buf);
color_buf[(1 << bpp) - 1].dummy_1 = -1;
alloc_pixel = 0;
}
uint8
color_pixel (struct splash_screen_color *color)
{
int i;
color->dummy_1 = -1;
for (i = 0; i <= alloc_pixel; i ++)
{
if (! memcmp (&color_buf[i], color, sizeof *color))
return i;
}
if (! memcmp (&color_buf[(1 << bpp) - 1], color, sizeof *color))
return (1 << bpp) - 1;
alloc_pixel ++;
if (alloc_pixel == (1 << bpp) - 1)
{
fprintf (stderr, "unable to find mapping for color %d %d %d\n",
color->red, color->green, color->blue);
exit (-1);
}
color_buf[alloc_pixel] = *color;
return alloc_pixel;
}
void
ppm_read_write_bits (int height, int width, int row_bytes,
FILE *fp, uint8 *bits)
{
int max_cmp_value;
uint8 *dst;
if (pixmap_p)
fscanf (fp, "%d", &max_cmp_value);
{
int r, b, p;
for (dst = bits, r = 0; r < height; r ++)
{
for (b = 0; b < row_bytes; b ++)
{
uint8 pixel = 0;
for (p = 1 << (3 - log2_bpp); p; p --)
{
if (pixmap_p)
{
uint32 red, green, blue;
struct splash_screen_color color;
fscanf (fp, "%d %d %d", &red, &green, &blue);
color.red = CW ((red * 65535) / max_cmp_value);
color.green = CW ((green * 65535) / max_cmp_value);
color.blue = CW ((blue * 65535) / max_cmp_value);
pixel = (pixel << bpp) | color_pixel (&color);
}
else
{
int bit;
#if 0
/* this didn't work on beaut */
fscanf (fp, "%1d", &bit);
#else
{
int c;
do
c = fgetc (fp);
while (c != EOF && c != '0' && c != '1');
switch (c)
{
case '0':
bit = 0;
break;
case '1':
bit = 1;
break;
default:
abort ();
break;
}
}
#endif
if (bpp != 1)
abort ();
switch (bit)
{
case 0:
pixel = pixel << 1; break;
case 1:
pixel = (pixel << 1) | bit; break;
default:
abort ();
}
}
}
*dst++ = pixel;
}
}
}
}
int
main (int argc, char *argv[])
{
char *paramfile;
char splashfile[1024], buttonfile[1024], outfile[1024];
int splashfd, buttonfd, outfd, paramfd;
FILE *splashfp, *buttonfp, *paramfp;
char buf[1024];
int splash_width, splash_height;
int button_width, button_height;
struct splash_screen_header header;
int splash_row_bytes, button_row_bytes;
uint8 *splash_bits, *button_bits;
int retval, i;
if (argc != 2)
{
fprintf (stderr, "usage: %s paramfile\n", *argv);
exit (-1);
}
paramfile = argv[1];
paramfd = open (paramfile, O_RDONLY);
if (paramfd == -1)
errno_fatal ("open %s", paramfile);
paramfp = fdopen (paramfd, "r");
if (paramfp == NULL)
errno_fatal ("fdopen");
fscanf (paramfp, "splash %s\n", splashfile);
fscanf (paramfp, "button %s\n", buttonfile);
fscanf (paramfp, "out %s\n", outfile);
fprintf (stderr, "\
splash file `%s'\n\
button file `%s'\n\
output file `%s'\n",
splashfile, buttonfile, outfile);
splashfd = open (splashfile, O_RDONLY);
if (splashfd == -1)
errno_fatal ("open %s", splashfile);
splashfp = fdopen (splashfd, "r");
if (splashfp == NULL)
errno_fatal ("fdopen");
buttonfd = open (buttonfile, O_RDONLY);
if (buttonfd == -1)
errno_fatal ("open %s", buttonfile);
buttonfp = fdopen (buttonfd, "r");
if (buttonfp == NULL)
errno_fatal ("fdopen");
outfd = open (outfile, O_WRONLY | O_CREAT | O_TRUNC, 0666);
if (outfd == -1)
errno_fatal ("open %s", outfile);
fscanf (paramfp, "bpp %d\n", &bpp);
switch (bpp)
{
case 8: log2_bpp = 3; break;
case 4: log2_bpp = 2; break;
case 2: log2_bpp = 1; break;
case 1: log2_bpp = 0; break;
default:
abort ();
}
{
int16 n_buttons;
fscanf (paramfp, "n_buttons %hd\n", &n_buttons);
for (i = 0; i < n_buttons; i ++)
{
int16 top, left, bottom, right;
struct splash_screen_rect *rect;
fscanf (paramfp, "rect %hd %hd %hd %hd\n",
&top, &left, &bottom, &right);
rect = &header.button_rects[i];
rect->top = CW (top);
rect->left = CW (left);
rect->bottom = CW (bottom);
rect->right = CW (right);
}
header.n_buttons = CW (n_buttons);
}
init_color_buf ();
{
uint32 red, green, blue;
struct splash_screen_color color;
fscanf (paramfp, "bk_color %d %d %d", &red, &green, &blue);
color.red = CW (red);
color.green = CW (green);
color.blue = CW (blue);
header.bg_pixel = color_pixel (&color);
}
fscanf (splashfp, "%s", buf);
if (! strcmp (buf, "P3"))
pixmap_p = TRUE;
else if (! strcmp (buf, "P1"))
pixmap_p = FALSE;
else
{
fprintf (stderr, "ppm type must be `P3' or `P1'\n");
exit (-1);
}
fscanf (splashfp, "%d %d", &splash_width, &splash_height);
if (splash_width != SPLASH_SCREEN_WIDTH
|| splash_height != SPLASH_SCREEN_HEIGHT)
{
fprintf (stderr,
"ppm width and height must be %d and %d, respectively\n",
SPLASH_SCREEN_WIDTH, SPLASH_SCREEN_HEIGHT);
exit (-1);
}
splash_row_bytes = splash_width >> (3 - log2_bpp);
splash_bits = malloc (splash_row_bytes * splash_height);
if (splash_bits == NULL)
{
fprintf (stderr, "unable to allocate `%d' bytes for bits buffer\n",
splash_row_bytes * splash_height);
exit (-1);
}
ppm_read_write_bits (splash_height, splash_width, splash_row_bytes,
splashfp, splash_bits);
fscanf (buttonfp, "%s", buf);
if (! strcmp (buf, "P3"))
pixmap_p = TRUE;
else if (! strcmp (buf, "P1"))
pixmap_p = FALSE;
else
{
fprintf (stderr, "ppm type must be `P3' or `P1'\n");
exit (-1);
}
fscanf (buttonfp, "%d %d", &button_width, &button_height);
if (button_width > splash_width || button_height > splash_height)
{
fprintf (stderr, "button image cannot be larger than splash image\n");
exit (-1);
}
if (button_width & ((1 << (3 - log2_bpp)) - 1))
{
fprintf (stderr, "button but be intergral number of bytes wide");
exit (-1);
}
button_row_bytes = button_width >> (3 - log2_bpp);
button_bits = malloc (button_row_bytes * button_height);
if (button_bits == NULL)
{
fprintf (stderr, "unable to allocate `%d' bytes for bits buffer\n",
button_row_bytes * button_height);
exit (-1);
}
ppm_read_write_bits (button_height, button_width, button_row_bytes,
buttonfp, button_bits);
header.button_height = CW (button_height);
header.button_y = CW (splash_height - 12 - button_height);
header.button_x_byte = CW ((splash_width - 16 - button_width)
>> (3 - log2_bpp));
header.button_row_bytes = CL (button_row_bytes);
header.bpp = CL (bpp);
header.log2_bpp = CL (log2_bpp);
header.color_count = CL (1 << bpp);
header.color_offset = CL (sizeof header);
header.splash_bits_offset = CL (sizeof header + (sizeof *color_buf << bpp));
header.button_bits_offset = CL (CL (header.splash_bits_offset)
+ splash_row_bytes * splash_height);
retval = write (outfd, &header, sizeof header);
if (retval != sizeof header)
errno_fatal ("write");
retval = write (outfd, color_buf, sizeof *color_buf << bpp);
if (retval != sizeof *color_buf << bpp)
errno_fatal ("write");
retval = write (outfd, splash_bits, splash_row_bytes * splash_height);
if (retval != splash_row_bytes * splash_height)
errno_fatal ("%d = write", retval);
retval = write (outfd, button_bits, button_row_bytes * button_height);
if (retval != button_row_bytes * button_height)
errno_fatal ("%d = write", retval);
fclose (splashfp);
fclose (buttonfp);
close (splashfd);
close (buttonfd);
close (outfd);
exit (EXIT_SUCCESS);
}