aboutsummaryrefslogtreecommitdiffstats
path: root/com32/lib/sys/vesa/background.c
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2006-08-28 00:28:31 -0700
committerH. Peter Anvin <hpa@zytor.com>2006-08-28 00:28:31 -0700
commit185b1c3a6c1f3ba8566507f1d8fe555480495a9c (patch)
treea7d8b1cad0ba798617ceec4b783f3937c23a8b54 /com32/lib/sys/vesa/background.c
parentb76cbd9c17c8001bdba243dffe6df0199b2cf049 (diff)
downloadsyslinux-185b1c3a6c1f3ba8566507f1d8fe555480495a9c.tar.gz
syslinux-185b1c3a6c1f3ba8566507f1d8fe555480495a9c.tar.xz
syslinux-185b1c3a6c1f3ba8566507f1d8fe555480495a9c.zip
More work on VESA graphical console support
Diffstat (limited to 'com32/lib/sys/vesa/background.c')
-rw-r--r--com32/lib/sys/vesa/background.c171
1 files changed, 171 insertions, 0 deletions
diff --git a/com32/lib/sys/vesa/background.c b/com32/lib/sys/vesa/background.c
new file mode 100644
index 00000000..7de2d5a4
--- /dev/null
+++ b/com32/lib/sys/vesa/background.c
@@ -0,0 +1,171 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2006 H. Peter Anvin - All Rights Reserved
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <stdio.h>
+#include <png.h>
+#include <com32.h>
+#include "vesa.h"
+#include "video.h"
+
+static void draw_background(void)
+{
+ uint32_t *outp = (uint32_t *)__vesa_info.mi.lfb_ptr;
+ uint32_t *inp = (uint32_t *)__vesacon_background;
+ size_t n = sizeof __vesacon_background;
+ uint32_t v;
+
+ while (n--) {
+ v = *inp++;
+ *outp++ = (__vesacon_alpha_tbl[(uint8_t)(v >> 16)][0] << 16)|
+ (__vesacon_alpha_tbl[(uint8_t)(v >> 8)][0] << 8)|
+ (__vesacon_alpha_tbl[(uint8_t)v][0]);
+ }
+}
+
+int vesacon_load_background(const char *filename)
+{
+ FILE *fp;
+ uint8_t header[8];
+ png_structp png_ptr = NULL;
+ png_infop info_ptr = NULL;
+ png_infop end_ptr = NULL;
+ png_color_16p image_background;
+ static const png_color_16 my_background = {0,0,0,0,0};
+ double gamma;
+ const double screen_gamma = 2.2;
+ png_bytep row_pointers[VIDEO_Y_SIZE];
+ int passes;
+ int i;
+ int rv = -1;
+
+ if (!filename) {
+ draw_background();
+ return 0;
+ }
+
+ fp = fopen(filename, "r");
+
+ if (!fp)
+ goto err;
+
+ png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
+ NULL, NULL, NULL);
+
+ info_ptr = png_create_info_struct(png_ptr);
+ end_ptr = png_create_info_struct(png_ptr);
+
+ if (fread(header, 1, 8, fp) != 8 || png_sig_cmp(header, 0, 8) ||
+ !png_ptr || !info_ptr || !end_ptr ||
+ setjmp(png_jmpbuf(png_ptr)))
+ goto err;
+
+ png_init_io(png_ptr, fp);
+ png_set_sig_bytes(png_ptr, 8);
+
+ png_set_user_limits(png_ptr, VIDEO_X_SIZE, VIDEO_Y_SIZE);
+
+ png_read_info(png_ptr, info_ptr);
+
+ /* Set the appropriate set of transformations. We need to end up
+ with 32-bit BGRA format, no more, no less. */
+
+ switch (info_ptr->color_type) {
+ case PNG_COLOR_TYPE_GRAY_ALPHA:
+ png_set_gray_to_rgb(png_ptr);
+ /* fall through */
+
+ case PNG_COLOR_TYPE_RGB_ALPHA:
+ break;
+
+ case PNG_COLOR_TYPE_GRAY:
+ png_set_gray_to_rgb(png_ptr);
+ /* fall through */
+
+ case PNG_COLOR_TYPE_RGB:
+ if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
+ png_set_tRNS_to_alpha(png_ptr);
+ else
+ png_set_add_alpha(png_ptr, ~0, PNG_FILLER_AFTER);
+ break;
+
+ case PNG_COLOR_TYPE_PALETTE:
+ png_set_palette_to_rgb(png_ptr);
+ break;
+
+ default:
+ /* Huh? */
+ break;
+ }
+
+ png_set_bgr(png_ptr);
+
+ if (png_get_bKGD(png_ptr, info_ptr, &image_background))
+ png_set_background(png_ptr, image_background,
+ PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
+ else
+ png_set_background(png_ptr, &my_background,
+ PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
+
+
+ if (info_ptr->bit_depth == 16)
+ png_set_strip_16(png_ptr);
+ else if (info_ptr->bit_depth < 8)
+ png_set_packing(png_ptr);
+
+ if (png_get_gAMA(png_ptr, info_ptr, &gamma))
+ png_set_gamma(png_ptr, screen_gamma, gamma);
+ else
+ png_set_gamma(png_ptr, screen_gamma, 0.45455);
+
+ /* Whew! Now we should get the stuff we want... */
+ for (i = 0; i < info_ptr->height; i++)
+ row_pointers[i] = (png_bytep *)__vesacon_background[i];
+
+ passes = png_set_interlace_handling(png_ptr);
+
+ for (i = 0; i < passes; i++)
+ png_read_rows(png_ptr, row_pointers, NULL, info_ptr->height);
+
+ /* This actually displays the stuff */
+ draw_background();
+
+ rv = 0;
+
+ err:
+ if (png_ptr)
+ png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
+ if (fp)
+ fclose(fp);
+ return rv;
+}
+
+int __vesacon_init_background(void)
+{
+ memset(__vesacon_background, 0, sizeof __vesacon_background);
+
+ /* The VESA BIOS has already cleared the screen */
+}