[systemd-devel] [PATCH 7/8] add ppm2bgrx utility

Joonas Lahtinen joonas.lahtinen at linux.intel.com
Mon Dec 9 23:51:03 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