[systemd-devel] [PATCH v2 7/8] add ppm2bgrx utility
Joonas Lahtinen
joonas.lahtinen at linux.intel.com
Tue Dec 10 01:23:51 PST 2013
Add utility to convert 8-bit PPM files into UEFI GOP supported BGRX
files to be used as splash screens.
Signed-off-by: Joonas Lahtinen <joonas.lahtinen at linux.intel.com>
Reviewed-by: Mikko Ylinen <mikko.ylinen at intel.com>
Acked-by: Darren Hart <dvhart at linux.intel.com>
---
.gitignore | 1 +
Makefile.am | 12 ++++
README.gop | 10 +++
utils/ppm2bgrx.c | 199 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 222 insertions(+)
create mode 100644 utils/ppm2bgrx.c
diff --git a/.gitignore b/.gitignore
index 047bb03..c4e337e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,6 +12,7 @@
/gummibootia32.efi
/gummibootx64.efi
/test-disk
+/ppm2bgrx
Makefile
aclocal.m4
diff --git a/Makefile.am b/Makefile.am
index 7922f00..52486df 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -53,6 +53,18 @@ gummiboot_CFLAGS = \
gummiboot_LDADD = \
$(BLKID_LIBS)
+if ENABLE_GOP
+bin_PROGRAMS += ppm2bgrx
+ppm2bgrx_SOURCES = \
+ utils/ppm2bgrx.c
+
+ppm2bgrx_CPPFLAGS = \
+ $(AM_CPPFLAGS)
+
+ppm2bgrx_CFLAGS = \
+ $(AM_CFLAGS)
+endif
+
if ENABLE_MANPAGES
%.8: %.xml
$(AM_V_GEN)$(XSLTPROC) -o $@ --nonet \
diff --git a/README.gop b/README.gop
index fef8882..5481b7b 100644
--- a/README.gop
+++ b/README.gop
@@ -44,3 +44,13 @@ Combined with the i915.fastboot patches for detecting the BIOS/UEFI initialized
graphics mode and using weston with --current-mode option you should be able to
keep the graphical splash screen drawn during gummiboot execution to stay on the
screen until the desktop shell is drawn. How cool is that?
+
+CONVERTING SPLASH SCREEN TO SUITABLE FORMAT
+
+To convert your preferred splash screen image to the required BGRX format you
+can use the supplied ppm2bgrx program. But first you need to use GIMP or some
+other image editing program to convert the image to 8-bit PPM format which the
+ppm2bgrx program can understand. After that it is simply a matter of running one
+command:
+
+$ ppm2bgrx input.ppm output.bgrx
diff --git a/utils/ppm2bgrx.c b/utils/ppm2bgrx.c
new file mode 100644
index 0000000..28c9ed1
--- /dev/null
+++ b/utils/ppm2bgrx.c
@@ -0,0 +1,199 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/*
+ * Simple UEFI boot loader which executes configured EFI images, where the
+ * default entry is selected by a configured pattern (glob) or an on-screen
+ * menu.
+ *
+ * All gummiboot code is LGPL not GPL, to stay out of politics and to give
+ * the freedom of copying code from programs to possible future libraries.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * Copyright (C) 2013 Intel Corporation, EFI GOP parts
+ * Authored by Joonas Lahtinen <joonas.lahtinen at linux.intel.com>
+ *
+ * "Everything should be made as simple as possible, but not simpler."
+ * -- Albert Einstein
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+static char* ppm_readline(FILE* stream, int skip_ws) {
+ int c, skip;
+ size_t i, buf_size;
+ char* buf;
+
+ /* Guess for initial maximum line size for PPM file headers. */
+ buf_size = 32;
+ buf = malloc(buf_size);
+ if (!buf)
+ goto err;
+
+ if (skip_ws) {
+ do {
+ if (ferror(stream))
+ goto err2;
+ c = fgetc(stream);
+ if (c == EOF)
+ goto err2;
+ } while(strchr(" \t\r\n", c));
+ }
+start_line:
+ skip = 0;
+ i = 0;
+
+ while (!ferror(stream)) {
+ if (skip_ws)
+ skip_ws = 0;
+ else
+ c = fgetc(stream);
+
+ if (c == EOF)
+ break;
+ if ((i == 0) && (c == '#'))
+ skip = 1;
+ if (strchr(skip ? "\r\n" : " \t\r\n", c)) {
+ if (skip)
+ goto start_line;
+ break;
+ }
+ if (i >= buf_size - 1) {
+ buf = realloc(buf, buf_size *= 2);
+ if (!buf)
+ goto err;
+ }
+ buf[i++] = c;
+ }
+
+ if (skip)
+ goto err2;
+ if (!i)
+ goto err;
+ buf[i] = 0;
+ return buf;
+err2:
+ free(buf);
+err:
+ return NULL;
+}
+
+int main(int argc, char* argv[]) {
+ FILE* input;
+ FILE* output;
+ char* line;
+ int w,h,maxval;
+ long npixels;
+ unsigned char binary[2];
+ int i;
+
+ if ((argc < 2) || !strcmp("-", argv[1])) {
+ input = stdin;
+ } else {
+ input = fopen(argv[1], "r");
+ if (!input) {
+ fprintf(stderr, "ERROR: Couldn't open file \'%s\' for reading.!\n", argv[1]);
+ goto err;
+ }
+ }
+
+ if (argc < 3 || !strcmp("-", argv[2])) {
+ output = stdout;
+ } else {
+ output = fopen(argv[2], "w");
+ if (!output) {
+ fprintf(stderr, "ERROR: Couldn't open file \'%s\' for writing.!\n", argv[2]);
+ goto err2;
+ }
+ }
+
+ line = ppm_readline(input, 0);
+ if (!line)
+ goto err3;
+ if (strcmp(line, "P6")) {
+ fprintf(stderr, "ERROR: Not a valid PPM file (bad header)!\n");
+ goto err4;
+ }
+ fwrite("BGRX", 4, 1, output);
+ free(line);
+
+ line = ppm_readline(input, 1);
+ if (!line)
+ goto err3;
+ w = atoi(line);
+ if (w <= 0) {
+ fprintf(stderr, "ERROR: Not a valid PPM file (zero or negative width)!\n");
+ goto err4;
+ }
+ free(line);
+ binary[0] = (unsigned char)((w >> 8) & 0xFF);
+ binary[1] = (unsigned char)((w >> 0) & 0xFF);
+ fwrite(binary, sizeof(binary), 1, output);
+
+ line = ppm_readline(input, 1);
+ if (!line)
+ goto err3;
+ h = atoi(line);
+ if (h <= 0) {
+ fprintf(stderr, "ERROR: Not a valid PPM file (zero or negative height)!\n");
+ goto err4;
+ }
+ free(line);
+ binary[0] = (unsigned char)((h >> 8) & 0xFF);
+ binary[1] = (unsigned char)((h >> 0) & 0xFF);
+ fwrite(binary, sizeof(binary), 1, output);
+
+ line = ppm_readline(input, 1);
+ if (!line)
+ goto err3;
+ maxval = atoi(line);
+ if (maxval != 0xFF) {
+ fprintf(stderr, "ERROR: Not a PPM file we can consume (not 8-bit)!\n");
+ goto err4;
+ }
+ free(line);
+
+ npixels = (long)w*(long)h;
+
+ for (i = 0; i < npixels; ++i)
+ {
+ unsigned char pix_in[3];
+ unsigned char pix_out[4];
+ if (ferror(input) || ferror(output))
+ goto err3;
+ if (fread(pix_in, sizeof(pix_in), 1, input) < sizeof(pix_in)) {
+ fprintf(stderr, "ERROR: Unexpected end-of-file!\n");
+ goto err3;
+ }
+ pix_out[0] = pix_in[2];
+ pix_out[1] = pix_in[1];
+ pix_out[2] = pix_in[0];
+ pix_out[3] = 0;
+ if (fwrite(pix_out, sizeof(pix_out), 1, output) < sizeof(pix_out)) {
+ fprintf(stderr, "ERROR: Unable to write to file!\n");
+ goto err3;
+ }
+ }
+ fclose(input);
+ fclose(output);
+ return EXIT_SUCCESS;
+err4:
+ free(line);
+err3:
+ fclose(output);
+err2:
+ fclose(input);
+err:
+ return EXIT_FAILURE;
+}
+
--
1.8.1.4
More information about the systemd-devel
mailing list