This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project gfxprim.git.
The branch, master has been updated
via f5e28f46785b6f44488672e5a1a6a878137a44be (commit)
from a5f3ffffa6adc218386bcec41f5cd1ebe691a7df (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://repo.or.cz/w/gfxprim.git/commit/f5e28f46785b6f44488672e5a1a6a878137a…
commit f5e28f46785b6f44488672e5a1a6a878137a44be
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Fri Oct 19 23:30:11 2012 +0200
tests: core: Created GetPutPixel test.
diff --git a/tests/core/GetPutPixel.gen.c.t b/tests/core/GetPutPixel.gen.c.t
new file mode 100644
index 0000000..b462bce
--- /dev/null
+++ b/tests/core/GetPutPixel.gen.c.t
@@ -0,0 +1,122 @@
+/*****************************************************************************
+ * This file is part of gfxprim library. *
+ * *
+ * Gfxprim 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. *
+ * *
+ * Gfxprim 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. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with gfxprim; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
+ * Boston, MA 02110-1301 USA *
+ * *
+ * Copyright (C) 2009-2012 Cyril Hrubis <metan(a)ucw.cz> *
+ * *
+ *****************************************************************************/
+
+%% extends "base.test.c.t"
+
+%% block body
+
+#include <stdio.h>
+
+#include <core/GP_Context.h>
+#include <core/GP_GetPutPixel.h>
+
+#include "tst_test.h"
+
+static void fill_context(GP_Context *c, GP_Pixel p)
+{
+ GP_Coord x, y;
+
+ for (x = 0; x < c->w; x++)
+ for (y = 0; y < c->h; y++)
+ GP_PutPixel(c, x, y, p);
+}
+
+static int check_filled(GP_Context *c)
+{
+ GP_Coord x, y;
+ GP_Pixel p;
+
+ p = GP_GetPixel(c, 0, 0);
+
+ for (x = 0; x < c->w; x++)
+ for (y = 0; y < c->h; y++)
+ if (p != GP_GetPixel(c, x, y)) {
+ tst_report(0, "Pixels different %i %i", x, y);
+ return 1;
+ }
+
+ return 0;
+}
+
+static int try_pattern(GP_Context *c, GP_Pixel p)
+{
+ fill_context(c, p);
+
+ tst_report(0, "Filling pattern 0x%x", p);
+
+ if (check_filled(c))
+ return 1;
+
+ return 0;
+}
+
+%% for pt in pixeltypes
+%% if not pt.is_unknown()
+static int GetPutPixel_{{ pt.name }}(void)
+{
+ GP_Context *c;
+ int err = 0;
+
+ c = GP_ContextAlloc(100, 100, GP_PIXEL_{{ pt.name }});
+
+ if (c == NULL) {
+ tst_report(0, "GP_ContextAlloc() failed");
+ return TST_FAILED;
+ }
+
+ if (try_pattern(c, 0x55555555 & {{ 2 ** pt.pixelsize.size - 1}}))
+ err++;
+
+ if (try_pattern(c, 0xaaaaaaaa & {{ 2 ** pt.pixelsize.size - 1}}))
+ err++;
+
+ if (try_pattern(c, 0x0f0f0f0f & {{ 2 ** pt.pixelsize.size - 1}}))
+ err++;
+
+ if (try_pattern(c, 0xf0f0f0f0 & {{ 2 ** pt.pixelsize.size - 1}}))
+ err++;
+
+ GP_ContextFree(c);
+
+ if (err)
+ return TST_FAILED;
+
+ return TST_SUCCESS;
+}
+%% endif
+%% endfor
+
+const struct tst_suite tst_suite = {
+ .suite_name = "GetPutPixel Testsuite",
+ .tests = {
+%% for pt in pixeltypes
+%% if not pt.is_unknown()
+ {.name = "GetPutPixel {{ pt.name }}",
+ .tst_fn = GetPutPixel_{{ pt.name }}},
+%% endif
+%% endfor
+
+ {.name = NULL}
+ }
+};
+
+%% endblock body
diff --git a/tests/core/Makefile b/tests/core/Makefile
index 6b8b9a0..54d105a 100644
--- a/tests/core/Makefile
+++ b/tests/core/Makefile
@@ -7,9 +7,9 @@ CSOURCES=Context.c
# hack
LIBNAME=core
-GENSOURCES+=WritePixel_testsuite.gen.c
+GENSOURCES+=WritePixel_testsuite.gen.c GetPutPixel.gen.c
-APPS=WritePixel_testsuite.gen Context
+APPS=WritePixel_testsuite.gen Context GetPutPixel.gen
include ../tests.mk
diff --git a/tests/core/runtest.sh b/tests/core/runtest.sh
index a392647..7e20739 100755
--- a/tests/core/runtest.sh
+++ b/tests/core/runtest.sh
@@ -11,3 +11,4 @@ export LIBC_FATAL_STDERR_=1
LD_PRELOAD=`pwd`/../framework/libtst_preload.so LD_LIBRARY_PATH=../../build/ ./WritePixel_testsuite.gen "$@"
LD_PRELOAD=`pwd`/../framework/libtst_preload.so LD_LIBRARY_PATH=../../build/ ./Context "$@"
+LD_PRELOAD=`pwd`/../framework/libtst_preload.so LD_LIBRARY_PATH=../../build/ ./GetPutPixel.gen "$@"
-----------------------------------------------------------------------
Summary of changes:
tests/core/{Context.c => GetPutPixel.gen.c.t} | 127 ++++++++++++++-----------
tests/core/Makefile | 4 +-
tests/core/runtest.sh | 1 +
3 files changed, 74 insertions(+), 58 deletions(-)
copy tests/core/{Context.c => GetPutPixel.gen.c.t} (57%)
repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos(a)gmail.com
if you want to unsubscribe, or site admin admin(a)repo.or.cz if you receive
no reply.
--
gfxprim.git ("A simple 2D graphics library with emphasis on correctness and well-defined operation.")
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project gfxprim.git.
The branch, master has been updated
via a5f3ffffa6adc218386bcec41f5cd1ebe691a7df (commit)
from 54a1f43dff8349c620ab43306651236f9143e5ee (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://repo.or.cz/w/gfxprim.git/commit/a5f3ffffa6adc218386bcec41f5cd1ebe691…
commit a5f3ffffa6adc218386bcec41f5cd1ebe691a7df
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Fri Oct 19 22:16:01 2012 +0200
core+all: Finally GP_RetCode free.
diff --git a/doc/drawing_api.txt b/doc/drawing_api.txt
index 75b6aa2..0304138 100644
--- a/doc/drawing_api.txt
+++ b/doc/drawing_api.txt
@@ -247,8 +247,8 @@ typedef enum GP_TextAlign {
GP_VALIGN_BELOW = 0x40 /* below the point */
} GP_TextAlign;
-GP_RetCode GP_Text(GP_Context *context, const GP_TextStyle *style,
- int x, int y, int align, const char *str, GP_Pixel pixel);
+void GP_Text(GP_Context *context, const GP_TextStyle *style,
+ int x, int y, int align, const char *str, GP_Pixel pixel);
--------------------------------------------------------------------------------
Draws text at the position x and y; the alignment of the text in relation
diff --git a/include/SDL/GP_SDL_Context.h b/include/SDL/GP_SDL_Context.h
index af53f54..5f27a4a 100644
--- a/include/SDL/GP_SDL_Context.h
+++ b/include/SDL/GP_SDL_Context.h
@@ -27,8 +27,7 @@
#define GP_SDL_CONTEXT_H
#include "GP.h"
-#include "core/GP_RetCode.h"
-GP_RetCode GP_SDL_ContextFromSurface(GP_Context *context, SDL_Surface *surf);
+int GP_SDL_ContextFromSurface(GP_Context *context, SDL_Surface *surf);
#endif /* GP_SDL_CONTEXT_H */
diff --git a/include/SDL/GP_SDL_VideoInit.h b/include/SDL/GP_SDL_VideoInit.h
index 99927b6..ad26c10 100644
--- a/include/SDL/GP_SDL_VideoInit.h
+++ b/include/SDL/GP_SDL_VideoInit.h
@@ -27,9 +27,8 @@
#define GP_SDL_VIDEOINIT_H
#include "GP.h"
-#include "core/GP_RetCode.h"
-GP_RetCode GP_SDL_VideoInit(GP_Context *context, int width, int height,
+int GP_SDL_VideoInit(GP_Context *context, int width, int height,
int argc, char **argv);
#endif /* GP_SDL_VIDEOINIT_H */
diff --git a/include/core/GP_RetCode.h b/include/core/GP_RetCode.h
deleted file mode 100644
index ce875fd..0000000
--- a/include/core/GP_RetCode.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*****************************************************************************
- * This file is part of gfxprim library. *
- * *
- * Gfxprim 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. *
- * *
- * Gfxprim 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. *
- * *
- * You should have received a copy of the GNU Lesser General Public *
- * License along with gfxprim; if not, write to the Free Software *
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
- * Boston, MA 02110-1301 USA *
- * *
- * Copyright (C) 2009-2010 Jiri "BlueBear" Dluhos *
- * <jiri.bluebear.dluhos(a)gmail.com> *
- * *
- * Copyright (C) 2009-2011 Cyril Hrubis <metan(a)ucw.cz> *
- * *
- *****************************************************************************/
-
-#ifndef CORE_GP_RETCODE_H
-#define CORE_GP_RETCODE_H
-
-typedef enum GP_RetCode {
- GP_ESUCCESS,
- GP_EINVAL,
- GP_ENOIMPL,
- GP_EUNPRECISE,
- GP_ENULLPTR, /* some argument was unexpectedly NULL */
- GP_ENOBACKEND, /* no backend available */
- GP_EBACKENDLOST, /* lost connection to the backend */
- GP_EBADCONTEXT, /* context contains invalid data */
- GP_EBADFILE, /* error in file, or bad file format */
- GP_ENOENT, /* no such file or another object */
- GP_ENOMEM, /* not enough memory */
- GP_EINTR, /* operation interrupted by user */
- GP_EMAX,
-} GP_RetCode;
-
-const char *GP_RetCodeName(GP_RetCode code);
-
-#endif /* CORE_GP_RETCODE_H */
diff --git a/libs/SDL/GP_SDL_Context.c b/libs/SDL/GP_SDL_Context.c
index 5ced9cc..cbe5ca4 100644
--- a/libs/SDL/GP_SDL_Context.c
+++ b/libs/SDL/GP_SDL_Context.c
@@ -31,14 +31,14 @@
#include "GP_SDL.h"
-GP_RetCode GP_SDL_ContextFromSurface(GP_Context *context, SDL_Surface *surf)
+int GP_SDL_ContextFromSurface(GP_Context *context, SDL_Surface *surf)
{
if (surf == NULL || surf->pixels == NULL || context == NULL)
- return GP_ENULLPTR;
+ return 1;
/* sanity checks on the SDL surface */
if (surf->format->BytesPerPixel == 0 || surf->format->BytesPerPixel > 4)
- return GP_ENOIMPL;
+ return 1;
enum GP_PixelType pixeltype = GP_PixelRGBMatch(surf->format->Rmask,
surf->format->Gmask,
@@ -47,7 +47,7 @@ GP_RetCode GP_SDL_ContextFromSurface(GP_Context *context, SDL_Surface *surf)
surf->format->BitsPerPixel);
if (pixeltype == GP_PIXEL_UNKNOWN)
- return GP_ENOIMPL;
+ return 1;
/* basic structure and size */
context->pixels = surf->pixels;
@@ -62,7 +62,7 @@ GP_RetCode GP_SDL_ContextFromSurface(GP_Context *context, SDL_Surface *surf)
context->x_swap = 0;
context->y_swap = 0;
- return GP_ESUCCESS;
+ return 0;
}
#endif /* HAVE_LIBSDL */
diff --git a/libs/SDL/GP_SDL_VideoInit.c b/libs/SDL/GP_SDL_VideoInit.c
index 8ce6419..b7462ff 100644
--- a/libs/SDL/GP_SDL_VideoInit.c
+++ b/libs/SDL/GP_SDL_VideoInit.c
@@ -33,11 +33,11 @@
#include <stdio.h>
#include <string.h>
-GP_RetCode GP_SDL_VideoInit(GP_Context *context, int width, int height,
+int GP_SDL_VideoInit(GP_Context *context, int width, int height,
int argc, char **argv)
{
if (context == NULL)
- return GP_ENULLPTR;
+ return 1;
/* switches that can be set on the command line */
int display_bpp = 0;
@@ -46,7 +46,7 @@ GP_RetCode GP_SDL_VideoInit(GP_Context *context, int width, int height,
if (argc > 0) {
if (argv == NULL)
- return GP_ENULLPTR;
+ return 1;
/* extract settings from the command line */
int i;
@@ -69,7 +69,7 @@ GP_RetCode GP_SDL_VideoInit(GP_Context *context, int width, int height,
fprintf(stderr, "Error: Could not initialize SDL: %sn",
SDL_GetError());
}
- return GP_EBACKENDLOST;
+ return 1;
}
SDL_Surface *display = NULL;
@@ -80,7 +80,7 @@ GP_RetCode GP_SDL_VideoInit(GP_Context *context, int width, int height,
SDL_GetError());
}
SDL_Quit();
- return GP_EINVAL;
+ return 1;
}
if (debug) {
@@ -94,18 +94,16 @@ GP_RetCode GP_SDL_VideoInit(GP_Context *context, int width, int height,
display->format->Bmask, display->format->Amask);
}
- GP_RetCode retcode;
- retcode = GP_SDL_ContextFromSurface(context, display);
- if (retcode != GP_ESUCCESS) {
+ int retcode = GP_SDL_ContextFromSurface(context, display);
+ if (retcode != 0) {
if (debug) {
- fprintf(stderr, "Error: Could not create context: %sn",
- GP_RetCodeName(retcode));
+ fprintf(stderr, "Error: Could not create context");
}
SDL_Quit();
return retcode;
}
- return GP_ESUCCESS;
+ return 0;
}
#endif /* HAVE_LIBSDL */
diff --git a/libs/core/GP_RetCode.c b/libs/core/GP_RetCode.c
deleted file mode 100644
index f14b5cc..0000000
--- a/libs/core/GP_RetCode.c
+++ /dev/null
@@ -1,50 +0,0 @@
-/*****************************************************************************
- * This file is part of gfxprim library. *
- * *
- * Gfxprim 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. *
- * *
- * Gfxprim 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. *
- * *
- * You should have received a copy of the GNU Lesser General Public *
- * License along with gfxprim; if not, write to the Free Software *
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
- * Boston, MA 02110-1301 USA *
- * *
- * Copyright (C) 2009-2010 Jiri "BlueBear" Dluhos *
- * <jiri.bluebear.dluhos(a)gmail.com> *
- * *
- * Copyright (C) 2009-2011 Cyril Hrubis <metan(a)ucw.cz> *
- * *
- *****************************************************************************/
-
-#include "GP_RetCode.h"
-
-/* Names of return codes; must be in the same order as the codes */
-static char *ret_code_names[] = {
- "Success",
- "Invalid operation",
- "Not implemented",
- "Imprecise result",
- "Unexpected null pointer",
- "No backend available",
- "Connection with backend lost",
- "Bad context",
- "Bad file",
- "Not found",
- "Not enough memory",
- "Operation interrupted"
-};
-
-const char *GP_RetCodeName(GP_RetCode code)
-{
- if (code >= GP_EMAX)
- return "Invalid return code";
-
- return ret_code_names[code];
-}
-----------------------------------------------------------------------
Summary of changes:
doc/drawing_api.txt | 4 +-
include/SDL/GP_SDL_Context.h | 3 +-
include/SDL/GP_SDL_VideoInit.h | 3 +-
include/core/GP_RetCode.h | 47 -------------------------------------
libs/SDL/GP_SDL_Context.c | 10 ++++----
libs/SDL/GP_SDL_VideoInit.c | 20 +++++++--------
libs/core/GP_RetCode.c | 50 ----------------------------------------
7 files changed, 18 insertions(+), 119 deletions(-)
delete mode 100644 include/core/GP_RetCode.h
delete mode 100644 libs/core/GP_RetCode.c
repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos(a)gmail.com
if you want to unsubscribe, or site admin admin(a)repo.or.cz if you receive
no reply.
--
gfxprim.git ("A simple 2D graphics library with emphasis on correctness and well-defined operation.")
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project gfxprim.git.
The branch, master has been updated
via 5f13bc0a920bfb4b903a6982b66a091825c4228e (commit)
via f4623e257dda0ce2f5afffc51be40f4f9022160e (commit)
via 5fb5fa695cc7e152587edb6f8d76ed531f0cc6cb (commit)
from 472dae1467a2add6bd116bd024c68ff6a5557534 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://repo.or.cz/w/gfxprim.git/commit/5f13bc0a920bfb4b903a6982b66a091825c4…
commit 5f13bc0a920bfb4b903a6982b66a091825c4228e
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Fri Oct 19 20:09:36 2012 +0200
tests: Remove trianglefps.
diff --git a/tests/SDL/Makefile b/tests/SDL/Makefile
index c11568d..9dd15e9 100644
--- a/tests/SDL/Makefile
+++ b/tests/SDL/Makefile
@@ -8,7 +8,7 @@ ifeq ($(HAVE_LIBSDL),yes)
CSOURCES=$(shell echo *.c)
APPS=pixeltest fonttest linetest randomshapetest- symbolstest textaligntest trianglefps blittest subcontext+ symbolstest textaligntest blittest subcontext aatest mixpixeltest
endif
diff --git a/tests/SDL/trianglefps.c b/tests/SDL/trianglefps.c
deleted file mode 100644
index 5eda430..0000000
--- a/tests/SDL/trianglefps.c
+++ /dev/null
@@ -1,186 +0,0 @@
-/*****************************************************************************
- * This file is part of gfxprim library. *
- * *
- * Gfxprim 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. *
- * *
- * Gfxprim 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. *
- * *
- * You should have received a copy of the GNU Lesser General Public *
- * License along with gfxprim; if not, write to the Free Software *
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
- * Boston, MA 02110-1301 USA *
- * *
- * Copyright (C) 2009-2010 Jiri "BlueBear" Dluhos *
- * <jiri.bluebear.dluhos(a)gmail.com> *
- * *
- * Copyright (C) 2009-2011 Cyril Hrubis <metan(a)ucw.cz> *
- * *
- *****************************************************************************/
-
-#include <math.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <SDL/SDL.h>
-
-#include "GP.h"
-#include "GP_SDL.h"
-
-/* Draw filled triangles? */
-int filled = 0;
-
-/* The surface used as a display (in fact it is a software surface). */
-SDL_Surface *display = NULL;
-GP_Context context;
-
-/* Frames per second. */
-int fps = 0, fps_min = 1000000, fps_max = 0;
-
-/* Color pixel values in display format. */
-GP_Pixel black, white;
-
-/*
- * Timer used for FPS measurement and key reactions.
- * SDL_USEREVENT is triggered each second.
- */
-
-SDL_TimerID timer;
-
-SDL_UserEvent timer_event;
-
-Uint32 timer_callback(__attribute__((unused)) Uint32 interval,
- __attribute__((unused)) void * param)
-{
- timer_event.type = SDL_USEREVENT;
- SDL_PushEvent((SDL_Event *) &timer_event);
- return 1000;
-}
-
-
-void draw_frame(void)
-{
- int x0 = 0;
- int y0 = random() % display->h;
- int x1 = display->w;
- int y1 = random() % display->h;
- int x2 = display->w/2;
- int y2 = random() % display->h;
-
- GP_Pixel pixel;
- pixel = GP_RGBToPixel(random() % 255, random() % 255,
- random() % 255, context.pixel_type);
-
- if (filled)
- GP_FillTriangle(&context, x0, y0, x1, y1, x2, y2, pixel);
- else
- GP_Triangle(&context, x0, y0, x1, y1, x2, y2, pixel);
-}
-
-void event_loop(void)
-{
- SDL_Event event;
-
- for (;;) {
- while (SDL_PollEvent(&event) > 0) {
- switch (event.type) {
- case SDL_USEREVENT:
- SDL_Flip(display);
- fprintf(stdout, "%d triangles/second, min = %d, max = %dr", fps, fps_min, fps_max);
- fflush(stdout);
-
- /* Update frames per second */
- if (fps < fps_min)
- fps_min = fps;
- if (fps > fps_max)
- fps_max = fps;
- fps = 0;
- break;
- case SDL_KEYDOWN:
- case SDL_QUIT:
- return;
- }
- }
- draw_frame();
- fps++;
- }
-}
-
-int main(int argc, char ** argv)
-{
- int bit_depth = 0;
-
- int i;
- for (i = 1; i < argc; i++) {
- if (strcmp(argv[i], "-f") == 0) {
- filled = 1;
- }
- else if (strcmp(argv[i], "-16") == 0) {
- bit_depth = 16;
- }
- else if (strcmp(argv[i], "-24") == 0) {
- bit_depth = 24;
- }
- else if (strcmp(argv[i], "-32") == 0) {
- bit_depth = 32;
- }
- }
-
- /* Initialize SDL */
- if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) != 0) {
- fprintf(stderr, "Could not initialize SDL: %sn", SDL_GetError());
- return 1;
- }
-
- /* Create a window with a software back surface */
- display = SDL_SetVideoMode(640, 480, bit_depth, SDL_SWSURFACE);
- if (display == NULL) {
- fprintf(stderr, "Could not open display: %sn", SDL_GetError());
- goto fail;
- }
-
- /* Print basic information about the surface */
- printf("Display surface properties:n");
- printf(" width: %4d, height: %4d, pitch: %4dn",
- display->w, display->h, display->pitch);
- printf(" bits per pixel: %2d, bytes per pixel: %2dn",
- display->format->BitsPerPixel, display->format->BytesPerPixel);
- printf("Machine properties:n");
- printf(" sizeof(int) = %u, sizeof(long) = %un",
- (unsigned int)sizeof(int), (unsigned int)sizeof(long));
-
- /* Set up a clipping rectangle to test proper clipping of pixels */
- SDL_Rect clip_rect = { 10, 10, 620, 460 };
- SDL_SetClipRect(display, &clip_rect);
-
- GP_SDL_ContextFromSurface(&context, display);
-
- white = GP_ColorToContextPixel(GP_COL_WHITE, &context);
- black = GP_ColorToContextPixel(GP_COL_BLACK, &context);
-
- /* Set up the timer */
- timer = SDL_AddTimer(1000, timer_callback, NULL);
- if (timer == 0) {
- fprintf(stderr, "Could not set up timer: %sn", SDL_GetError());
- goto fail;
- }
-
- /* Enter the event loop */
- event_loop();
-
- /* Preserve the last result by a newline */
- fprintf(stdout, "n");
-
- /* We're done */
- SDL_Quit();
- return 0;
-
-fail:
- SDL_Quit();
- return 1;
-}
-
http://repo.or.cz/w/gfxprim.git/commit/f4623e257dda0ce2f5afffc51be40f4f9022…
commit f4623e257dda0ce2f5afffc51be40f4f9022160e
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Fri Oct 19 20:06:47 2012 +0200
tests: Remove more unused files.
diff --git a/tests/common/GP_TestingRandom.c b/tests/common/GP_TestingRandom.c
deleted file mode 100644
index 17281a9..0000000
--- a/tests/common/GP_TestingRandom.c
+++ /dev/null
@@ -1,58 +0,0 @@
-/*****************************************************************************
- * This file is part of gfxprim library. *
- * *
- * Gfxprim 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. *
- * *
- * Gfxprim 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. *
- * *
- * You should have received a copy of the GNU Lesser General Public *
- * License along with gfxprim; if not, write to the Free Software *
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
- * Boston, MA 02110-1301 USA *
- * *
- * Copyright (C) 2011 Tomas Gavenciak <gavento(a)ucw.cz> *
- * *
- *****************************************************************************/
-
-#include <stdlib.h>
-
-#include "GP_Common.h"
-#include "GP_TestingRandom.h"
-
-/*
- * State array for testing random generator
- *
- * The idea is to have a seperate random generator for generating
- * random inputs for tests in case tested algorithms also use
- * the random generator. Change in the tested algorithm must not
- * change the input data generated for this or other part of the test.
- *
- * Take care when changing the values - unrelated test might start
- * exhibiting a bug, some tests may rely on the exact result.
- */
-#define GP_RandomStateSize 256
-static char GP_RandomTestingState[GP_RandomStateSize];
-static struct random_data GP_RandomTestingData;
-
-long int GP_TestingRandom(void)
-{
- int32_t r;
- GP_ASSERT(random_r(&GP_RandomTestingData, &r) == 0);
- return r;
-}
-
-void GP_InitTestingRandom(const char *text, uint64_t seed)
-{
- const char *p = text;
- for (; (p) && (*p); p++)
- seed = ((seed * 327) + *p) % 0x7B391D50A10A3LL; // TODO replace with large primes
- GP_ASSERT(initstate_r(seed, GP_RandomTestingState, GP_RandomStateSize,
- &GP_RandomTestingData) == 0);
-}
-
diff --git a/tests/common/GP_TestingRandom.h b/tests/common/GP_TestingRandom.h
deleted file mode 100644
index 9f267fb..0000000
--- a/tests/common/GP_TestingRandom.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*****************************************************************************
- * This file is part of gfxprim library. *
- * *
- * Gfxprim 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. *
- * *
- * Gfxprim 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. *
- * *
- * You should have received a copy of the GNU Lesser General Public *
- * License along with gfxprim; if not, write to the Free Software *
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
- * Boston, MA 02110-1301 USA *
- * *
- * Copyright (C) 2011 Tomas Gavenciak <gavento(a)ucw.cz> *
- * *
- *****************************************************************************/
-
-/*
- * These routines use a pseudorandom generator with internal state.
- * Use this only to provide tests with pseudo-random inputs.
- * The seed is initialized with the test name, so the random numbers
- * (and therefore inputs) are the same for a test, and do not depend
- * on random() called in the tested routines or other tests.
- */
-
-#ifndef GP_TESTING_RANDOM_H
-#define GP_TESTING_RANDOM_H
-
-#include <stdint.h>
-
-/*
- * Return next random value from the testing random generator
- */
-long int GP_TestingRandom(void);
-
-/*
- * Initialize the random generator to a seed computed from the given string
- * and the given seed value. Needs to be called at least once.
- *
- * The string may be for example the name of the test, the seed the number of test iteration.
- */
-void GP_InitTestingRandom(const char *text, uint64_t seed);
-
-#endif /* GP_TESTING_RANDOM_H */
diff --git a/tests/common/GP_Tests.c b/tests/common/GP_Tests.c
deleted file mode 100644
index 736c05c..0000000
--- a/tests/common/GP_Tests.c
+++ /dev/null
@@ -1,79 +0,0 @@
-/*****************************************************************************
- * This file is part of gfxprim library. *
- * *
- * Gfxprim 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. *
- * *
- * Gfxprim 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. *
- * *
- * You should have received a copy of the GNU Lesser General Public *
- * License along with gfxprim; if not, write to the Free Software *
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
- * Boston, MA 02110-1301 USA *
- * *
- * Copyright (C) 2011 Tomas Gavenciak <gavento(a)ucw.cz> *
- * *
- *****************************************************************************/
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <getopt.h>
-#include <check.h>
-
-typedef Suite* (SuiteFactory)(void);
-
-/*
- * Declare all the manualy created Suite-generating functions here:
- */
-
-SuiteFactory* manual_suites[] = {
- NULL /* Sentinel */
-};
-
-/*
- * Generated function creating and adding all the suites
- */
-
-void GP_AddSuitesToSRunner(SRunner *sr);
-
-
-const char usage[] = "Usage:n%s [-v] [-q]n";
-
-int main(int argc, char *argv[])
-{
- int verb = CK_NORMAL;
-
- int opt;
- while((opt = getopt(argc, argv, "vq")) >= 0)
- switch(opt) {
- case 'v':
- verb = CK_VERBOSE;
- break;
- case 'q':
- verb = CK_SILENT;
- break;
- default:
- fprintf(stderr, usage, argv[0]);
- return(EXIT_FAILURE);
- }
-
- SRunner *sr = srunner_create(NULL);
-
- SuiteFactory **s;
- for (s = manual_suites; *s; s++) {
- srunner_add_suite(sr, (*s)());
- }
- GP_AddSuitesToSRunner(sr);
-
- srunner_run_all(sr, verb);
- int number_failed = srunner_ntests_failed(sr);
- srunner_free(sr);
-
- return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
-}
diff --git a/tests/common/GP_Tests.h b/tests/common/GP_Tests.h
deleted file mode 100644
index 72c83bb..0000000
--- a/tests/common/GP_Tests.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/*****************************************************************************
- * This file is part of gfxprim library. *
- * *
- * Gfxprim 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. *
- * *
- * Gfxprim 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. *
- * *
- * You should have received a copy of the GNU Lesser General Public *
- * License along with gfxprim; if not, write to the Free Software *
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
- * Boston, MA 02110-1301 USA *
- * *
- * Copyright (C) 2011 Tomas Gavenciak <gavento(a)ucw.cz> *
- * *
- *****************************************************************************/
-
-/*
- * Wrappers around check.h unit-test library
- *
- * Create a .test.c file with (example):
- *
- * GP_SUITE(suite_name)
- *
- * GP_TEST(test1)
- * {
- * fail_unless(1 == 1);
- * fail_if(1 < 0, "Impossible!");
- * int i = 3;
- * if (1 + 1 == i) fail("Arrgh, 1 + 1 is %d", i);
- * }
- * GP_ENDTEST
- *
- * The tests are collected automatically by find_tests.py.
- * See below for more options.
- */
-
-#include <check.h>
-#include "GP_TestingRandom.h"
-
-/*
- * Helper macro to allow auto-generation of test-cases and suites.
- * Searched for by find_tests.py.
- *
- * Use alone on a line as
- * GP_TEST(testname)
- * or
- * GP_TEST(testname, "foo=1, bar='baz'")
- * The optional string is passed as parameters to Python dict() as parameters
- * for the testcase-generator.
- * Currently, the following parameters are recognized:
- * suite -- name of the suite
- * loop_start -- test will be repeated as with:
- * loop_end for (int _i = loop_start; _i < loop_end; i++) { ... }
- * expect_exit -- expect the function to exit with given exitcode
- * expect_signal -- expect the function to exit with given exitcode
- *
- * Parameters name, fname, line are used internally, do not use them
- */
-
-#define GP_TEST(name, ...) static void name(int); void GP_TEST_##name(int i) {- GP_InitTestingRandom( #name, i); name(i); } - START_TEST(name)
-
-#define GP_ENDTEST END_TEST
-
-/*
- * Helper macro to allow auto-generation of suites.
- * Defines suite from this point until EOF or redefinition.
- * Searched for by find_tests.py
- *
- * Use alone on a line as
- * GP_SUITE(suitename)
- */
-
-#define GP_SUITE(name, ...)
-
http://repo.or.cz/w/gfxprim.git/commit/5fb5fa695cc7e152587edb6f8d76ed531f0c…
commit 5fb5fa695cc7e152587edb6f8d76ed531f0cc6cb
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Fri Oct 19 20:04:09 2012 +0200
tests: core: Add simple context test.
diff --git a/tests/core/Context.c b/tests/core/Context.c
new file mode 100644
index 0000000..ec83876
--- /dev/null
+++ b/tests/core/Context.c
@@ -0,0 +1,107 @@
+/*****************************************************************************
+ * This file is part of gfxprim library. *
+ * *
+ * Gfxprim 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. *
+ * *
+ * Gfxprim 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. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with gfxprim; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
+ * Boston, MA 02110-1301 USA *
+ * *
+ * Copyright (C) 2009-2012 Cyril Hrubis <metan(a)ucw.cz> *
+ * *
+ *****************************************************************************/
+
+/*
+
+ Very basic GP_Context tests.
+
+ */
+
+#include <core/GP_Context.h>
+
+#include "tst_test.h"
+
+/*
+ * Check that Context is correctly allocated and freed
+ */
+static int Context_Alloc_Free(void)
+{
+ GP_Context *c;
+
+ c = GP_ContextAlloc(100, 200, GP_PIXEL_RGB888);
+
+ if (c == NULL) {
+ tst_report(0, "GP_ContextAlloc() failed");
+ return TST_FAILED;
+ }
+
+ /* Assert context properties */
+ if (c->bpp != 24) {
+ tst_report(0, "Context->bpp != 24 (== %i)", c->bpp);
+ return TST_FAILED;
+ }
+
+ if (c->bytes_per_row != 3 * c->w) {
+ tst_report(0, "Context->bytes_per_row != %i (== %i)",
+ 3 * c->w, c->bytes_per_row);
+ return TST_FAILED;
+ }
+
+ if (c->w != 100) {
+ tst_report(0, "Context->w != 100 (== %i)", c->w);
+ return TST_FAILED;
+ }
+
+ if (c->h != 200) {
+ tst_report(0, "Context->h != 200 (== %i)", c->h);
+ return TST_FAILED;
+ }
+
+ if (c->offset != 0) {
+ tst_report(0, "Context->offset != 0");
+ return TST_FAILED;
+ }
+
+ if (c->pixel_type != GP_PIXEL_RGB888) {
+ tst_report(0, "Context->pixel_type != GP_PIXEL_RGB888");
+ return TST_FAILED;
+ }
+
+ if (c->gamma != NULL) {
+ tst_report(0, "Context->gamma != NULL");
+ return TST_FAILED;
+ }
+
+ if (c->axes_swap != 0 || c->x_swap != 0 || c->y_swap != 0) {
+ tst_report(0, "Wrong default orientation %i %i %i",
+ c->axes_swap, c->x_swap, c->y_swap);
+ return TST_FAILED;
+ }
+
+ /* access the pixel buffer */
+ *(char*)GP_PIXEL_ADDR(c, 0, 0) = 0;
+ *(char*)GP_PIXEL_ADDR(c, 100, 100) = 0;
+
+ GP_ContextFree(c);
+
+ return TST_SUCCESS;
+}
+
+const struct tst_suite tst_suite = {
+ .suite_name = "Context Testsuite",
+ .tests = {
+ {.name = "Context Alloc Free", .tst_fn = Context_Alloc_Free,
+ .flags = TST_CHECK_MALLOC},
+
+ {.name = NULL},
+ }
+};
diff --git a/tests/core/Makefile b/tests/core/Makefile
index f030894..6b8b9a0 100644
--- a/tests/core/Makefile
+++ b/tests/core/Makefile
@@ -2,14 +2,14 @@ TOPDIR=../..
include $(TOPDIR)/pre.mk
-#CSOURCES=$(shell echo *.c)
+CSOURCES=Context.c
# hack
LIBNAME=core
GENSOURCES+=WritePixel_testsuite.gen.c
-APPS=WritePixel_testsuite.gen
+APPS=WritePixel_testsuite.gen Context
include ../tests.mk
diff --git a/tests/core/runtest.sh b/tests/core/runtest.sh
index 0a9821e..a392647 100755
--- a/tests/core/runtest.sh
+++ b/tests/core/runtest.sh
@@ -10,3 +10,4 @@
export LIBC_FATAL_STDERR_=1
LD_PRELOAD=`pwd`/../framework/libtst_preload.so LD_LIBRARY_PATH=../../build/ ./WritePixel_testsuite.gen "$@"
+LD_PRELOAD=`pwd`/../framework/libtst_preload.so LD_LIBRARY_PATH=../../build/ ./Context "$@"
-----------------------------------------------------------------------
Summary of changes:
tests/SDL/Makefile | 2 +-
tests/SDL/trianglefps.c | 186 -------------------------
tests/common/GP_TestingRandom.c | 58 --------
tests/common/GP_TestingRandom.h | 49 -------
tests/common/GP_Tests.c | 79 -----------
tests/common/GP_Tests.h | 82 -----------
tests/{framework/tst_job.h => core/Context.c} | 127 +++++++++--------
tests/core/Makefile | 4 +-
tests/core/runtest.sh | 1 +
9 files changed, 73 insertions(+), 515 deletions(-)
delete mode 100644 tests/SDL/trianglefps.c
delete mode 100644 tests/common/GP_TestingRandom.c
delete mode 100644 tests/common/GP_TestingRandom.h
delete mode 100644 tests/common/GP_Tests.c
delete mode 100644 tests/common/GP_Tests.h
copy tests/{framework/tst_job.h => core/Context.c} (51%)
repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos(a)gmail.com
if you want to unsubscribe, or site admin admin(a)repo.or.cz if you receive
no reply.
--
gfxprim.git ("A simple 2D graphics library with emphasis on correctness and well-defined operation.")
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project gfxprim.git.
The branch, master has been updated
via fccae75f5221a0307cb52a5e8d7aa6cf820ec6df (commit)
from 8caa76a32fdad0cc36b1a4ac6038b205f17b504e (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://repo.or.cz/w/gfxprim.git/commit/fccae75f5221a0307cb52a5e8d7aa6cf820e…
commit fccae75f5221a0307cb52a5e8d7aa6cf820ec6df
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sat Oct 13 20:23:37 2012 +0200
core: Remove unused GP_Counter.
diff --git a/include/core/GP_Core.h b/include/core/GP_Core.h
index cd5555d..d10152f 100644
--- a/include/core/GP_Core.h
+++ b/include/core/GP_Core.h
@@ -71,9 +71,6 @@
/* Threads utils */
#include "core/GP_Threads.h"
-/* Debug counters */
-#include "core/GP_Counter.h"
-
/* Mix Pixel */
#include "core/GP_MixPixels.h"
diff --git a/include/core/GP_Counter.h b/include/core/GP_Counter.h
deleted file mode 100644
index 0429df9..0000000
--- a/include/core/GP_Counter.h
+++ /dev/null
@@ -1,121 +0,0 @@
-/*****************************************************************************
- * This file is part of gfxprim library. *
- * *
- * Gfxprim 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. *
- * *
- * Gfxprim 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. *
- * *
- * You should have received a copy of the GNU Lesser General Public *
- * License along with gfxprim; if not, write to the Free Software *
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
- * Boston, MA 02110-1301 USA *
- * *
- * Copyright (C) 2011 Tomas Gavenciak <gavento(a)ucw.cz> *
- * Copyright (C) 2012 Cyril Hrubis <metan(a)ucw.cz> *
- * *
- *****************************************************************************/
-
-#ifndef CORE_GP_COUNTER_H
-#define CORE_GP_COUNTER_H
-
-/*
- * Simple global named 64-bit counters.
- *
- * Intended for accounting of expensive operations ("quantitative warnings").
- * All operations accept NULL as GP_Counter.
- *
- * If GP_IMPLEMENT_COUNTERS is undefined, all operations are NOP and
- * no memory is allocated.
- */
-#define GP_IMPLEMENT_COUNTERS
-
-/*
- * Maximum length of counter name,
- * maximum number of counters (~40 bytes each)
- */
-#define GP_COUNTER_NAME_LEN 24
-#define GP_COUNTER_MAX 256
-
-/*
- * Basic types.
- * Only use GP_Counter in your programs.
- */
-typedef int64_t GP_Counter_t;
-typedef GP_Counter_t *GP_Counter;
-
-/*
- * Increase a counter by 1.
- */
-static inline void GP_IncCounter(GP_Counter counter)
-{
-#ifdef GP_IMPLEMENT_COUNTERS
- if (!counter)
- return;
- (*counter)++;
-#endif /* GP_IMPLEMENT_COUNTERS */
-}
-
-/*
- * Increase a counter by delta (may be negative).
- * No checks for underflow.
- */
-static inline void GP_AddCounter(GP_Counter counter, GP_Counter_t delta)
-{
-#ifdef GP_IMPLEMENT_COUNTERS
- if (!counter)
- return;
- (*counter) += delta;
-#endif /* GP_IMPLEMENT_COUNTERS */
-}
-
-/*
- * Set counter to given value.
- */
-static inline void GP_SetCounter(GP_Counter counter, GP_Counter_t value)
-{
-#ifdef GP_IMPLEMENT_COUNTERS
- if (!counter)
- return;
- (*counter) = value;
-#endif /* GP_IMPLEMENT_COUNTERS */
-}
-
-/*
- * Return counter value
- */
-static inline GP_Counter_t GP_CounterVal(GP_Counter counter)
-{
-#ifdef GP_IMPLEMENT_COUNTERS
- if (!counter)
- return 0;
- return *counter;
-#else /* GP_IMPLEMENT_COUNTERS */
- return 0;
-#endif /* GP_IMPLEMENT_COUNTERS */
-}
-
-/*
- * Pretty-printing of all counters and their values to f
- * Includes info about counter-list overflow
- */
-#include <stdio.h>
-void GP_PrintCounters(FILE *f);
-
-/*
- * Lookup a counter by name, possibly creating a new one.
- *
- * May return NULL if no space is left in the counter list.
- * The returned value is not unallocated in any way.
- *
- * NOTE: Current implementation has very slow adds (O(current_counters)),
- * but the lookup is reasonably fast (bisection)
- */
-GP_Counter GP_GetCounter(const char *name);
-
-#endif /* CORE_GP_COUNTER_H */
diff --git a/libs/core/GP_Counter.c b/libs/core/GP_Counter.c
deleted file mode 100644
index 7ba619e..0000000
--- a/libs/core/GP_Counter.c
+++ /dev/null
@@ -1,109 +0,0 @@
-/*****************************************************************************
- * This file is part of gfxprim library. *
- * *
- * Gfxprim 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. *
- * *
- * Gfxprim 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. *
- * *
- * You should have received a copy of the GNU Lesser General Public *
- * License along with gfxprim; if not, write to the Free Software *
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
- * Boston, MA 02110-1301 USA *
- * *
- * Copyright (C) 2011 Tomas Gavenciak <gavento(a)ucw.cz> *
- * Copyright (C) 2012 Cyril Hrubis <metan(a)ucw.cz> *
- * *
- *****************************************************************************/
-
-#include <string.h>
-#include "GP_Common.h"
-#include "GP_Counter.h"
-
-/*
- * Internal struct used in counter list
- */
-struct GP_CounterRecord {
- char name[GP_COUNTER_NAME_LEN];
- GP_Counter counter;
-};
-
-/*
- * variables local to module (static)
- */
-#ifdef GP_IMPLEMENT_COUNTERS
-
-static GP_Counter_t GP_counters[GP_COUNTER_MAX];
-static int GP_used_counters = 0;
-static struct GP_CounterRecord GP_counter_list[GP_COUNTER_MAX];
-static GP_Counter_t GP_counter_list_overflow = 0;
-
-#endif /* GP_IMPLEMENT_COUNTERS */
-
-void GP_PrintCounters(FILE *f)
-{
-#ifdef GP_IMPLEMENT_COUNTERS
- int i;
- GP_CHECK(f != NULL);
- if (GP_used_counters == 0)
- fprintf(f, "[ no counters defined ]n");
- for (i = 0; i < GP_used_counters; i++)
- fprintf(f, "%*s : %llun", -GP_COUNTER_NAME_LEN,
- GP_counter_list[i].name,
- (long long unsigned int)*(GP_counter_list[i].counter));
- if (GP_counter_list_overflow > 0)
- fprintf(f, "[ unable to allocate new counter %llu times ]n",
- (long long unsigned int)GP_counter_list_overflow);
-#endif /* GP_IMPLEMENT_COUNTERS */
-}
-
-GP_Counter GP_GetCounter(const char *name)
-{
-#ifdef GP_IMPLEMENT_COUNTERS
- int l = 0;
- int r = GP_used_counters;
-
- GP_CHECK(name != NULL);
- GP_CHECK(strlen(name) + 1 <= GP_COUNTER_NAME_LEN);
-
- /*
- * Bisect GP_counter_list to find either the counter or a place for it
- * interval [l, r) (not incl. r)
- */
- while (r > l) {
- int med = (r + l) / 2; /* Here never equal to r, might be l */
- int cmp = strcmp(GP_counter_list[med].name, name);
- if (cmp == 0)
- return GP_counter_list[med].counter;
- if (cmp < 0)
- l = med + 1;
- else
- r = med;
- }
- GP_CHECK(l == r);
- if ((l < GP_used_counters) && (strcmp(GP_counter_list[l].name, name) == 0))
- return GP_counter_list[l].counter;
-
- /* Add a new counter */
- if (GP_used_counters >= GP_COUNTER_MAX) {
- GP_counter_list_overflow++;
- return NULL;
- }
-
- /* Move the counter records up and initialize a new one */
- memmove(GP_counter_list + l + 1, GP_counter_list + l,
- sizeof(struct GP_CounterRecord) * GP_used_counters - l);
- strcpy(GP_counter_list[l].name, name);
- GP_counter_list[l].counter = GP_counters + GP_used_counters;
-
- GP_used_counters++;
- return GP_counter_list[l].counter;
-#else /* GP_IMPLEMENT_COUNTERS */
- return NULL;
-#endif /* GP_IMPLEMENT_COUNTERS */
-}
diff --git a/pylib/gfxprim/core/core.i b/pylib/gfxprim/core/core.i
index 67777dd..6ddfc29 100644
--- a/pylib/gfxprim/core/core.i
+++ b/pylib/gfxprim/core/core.i
@@ -9,14 +9,11 @@
* Basic types and common methods
*/
-ERROR_ON_NULL(GP_GetCounter);
-
%include "GP_Common.h"
%include "GP_Core.h"
%include "GP_Debug.h"
%include "GP_Types.h"
%include "GP_Transform.h"
-%include "GP_Counter.h"
%include "GP_GetSetBits.h"
%include "GP_Transform.h"
%include "GP_ProgressCallback.h"
diff --git a/tests/core_old/GP_Counter.test.c b/tests/core_old/GP_Counter.test.c
deleted file mode 100644
index 6bd9ab7..0000000
--- a/tests/core_old/GP_Counter.test.c
+++ /dev/null
@@ -1,81 +0,0 @@
-/*****************************************************************************
- * This file is part of gfxprim library. *
- * *
- * Gfxprim 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. *
- * *
- * Gfxprim 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. *
- * *
- * You should have received a copy of the GNU Lesser General Public *
- * License along with gfxprim; if not, write to the Free Software *
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
- * Boston, MA 02110-1301 USA *
- * *
- * Copyright (C) 2011 Tomas Gavenciak <gavento(a)ucw.cz> *
- * *
- *****************************************************************************/
-
-#include <string.h>
-#include <stdio.h>
-
-#include "GP_Tests.h"
-#include "GP_Counter.h"
-
-GP_SUITE(GP_Counter)
-
-GP_TEST(Smoke)
-{
- fail_unless(GP_CounterVal(NULL) == 0);
- GP_IncCounter(NULL);
- GP_AddCounter(NULL, -10);
- fail_unless(GP_GetCounter("") != NULL);
-
- GP_IncCounter(GP_GetCounter("a"));
- fail_unless(GP_CounterVal(GP_GetCounter("a")) == 1);
-
- GP_PrintCounters(fopen("/dev/null","wt"));
-}
-END_TEST
-
-GP_TEST(Allocation)
-{
- /* random-like operations with counters,
- * should test reasonably many combinations */
- GP_SetCounter(GP_GetCounter("a"), 11);
- GP_AddCounter(GP_GetCounter("e"), -42);
- GP_Counter b = GP_GetCounter("b");
- GP_IncCounter(GP_GetCounter("a"));
- GP_GetCounter("d");
- GP_AddCounter(GP_GetCounter("c"), 21);
- GP_IncCounter(GP_GetCounter("b"));
- GP_AddCounter(GP_GetCounter("b"), -8);
- GP_IncCounter(b);
- GP_SetCounter(GP_GetCounter("f"), 91);
- GP_SetCounter(GP_GetCounter("f"), -1);
-
- fail_unless(GP_CounterVal(GP_GetCounter("a")) == 12);
- fail_unless(GP_CounterVal(GP_GetCounter("b")) == -6);
- fail_unless(GP_CounterVal(GP_GetCounter("c")) == 21);
- fail_unless(GP_CounterVal(GP_GetCounter("d")) == 0);
- fail_unless(GP_CounterVal(GP_GetCounter("e")) == -42);
- fail_unless(GP_CounterVal(GP_GetCounter("f")) == -1);
-}
-END_TEST
-
-GP_TEST(Overflow)
-{
- char buf[8];
- int i;
- for (i = 0; i < GP_COUNTER_MAX; i++) {
- sprintf(buf, "%d", i);
- fail_if(GP_GetCounter(buf) == NULL);
- }
- fail_unless(GP_GetCounter("next") == NULL);
-}
-END_TEST
-
-----------------------------------------------------------------------
Summary of changes:
include/core/GP_Core.h | 3 -
include/core/GP_Counter.h | 121 --------------------------------------
libs/core/GP_Counter.c | 109 ----------------------------------
pylib/gfxprim/core/core.i | 3 -
tests/core_old/GP_Counter.test.c | 81 -------------------------
5 files changed, 0 insertions(+), 317 deletions(-)
delete mode 100644 include/core/GP_Counter.h
delete mode 100644 libs/core/GP_Counter.c
delete mode 100644 tests/core_old/GP_Counter.test.c
repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos(a)gmail.com
if you want to unsubscribe, or site admin admin(a)repo.or.cz if you receive
no reply.
--
gfxprim.git ("A simple 2D graphics library with emphasis on correctness and well-defined operation.")
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project gfxprim.git.
The branch, master has been updated
via 7a5c61ef4059b02a846cdce2e19943dd1150d261 (commit)
via b27ea6e7962b7a22dbd9fdf48e9ffe2358c88097 (commit)
from d20862dc07b9b8858ca929d9b91caa1eb6d88bbc (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://repo.or.cz/w/gfxprim.git/commit/7a5c61ef4059b02a846cdce2e19943dd1150…
commit 7a5c61ef4059b02a846cdce2e19943dd1150d261
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sat Oct 13 20:07:08 2012 +0200
tests: loaders: Make use of some bmp images.
diff --git a/tests/Makefile b/tests/Makefile
index f4fc735..6181430 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -5,5 +5,6 @@ SUBDIRS=core SDL drivers framework loaders gfx
loaders: framework
gfx: framework
+core: framework
include $(TOPDIR)/post.mk
diff --git a/tests/loaders/Makefile b/tests/loaders/Makefile
index 8fb8b15..f076cd7 100644
--- a/tests/loaders/Makefile
+++ b/tests/loaders/Makefile
@@ -12,7 +12,7 @@ APPS=loaders_suite
$(APPS): ../framework/libtst.a
-CLEAN+=libtst_preload.so log.html log.json
+CLEAN+=log.html log.json
include $(TOPDIR)/app.mk
include $(TOPDIR)/post.mk
diff --git a/tests/loaders/loaders_suite.c b/tests/loaders/loaders_suite.c
index aa2fa92..41ab097 100644
--- a/tests/loaders/loaders_suite.c
+++ b/tests/loaders/loaders_suite.c
@@ -493,6 +493,74 @@ static int test_Load(void)
return TST_SKIPPED;
}
+static int test_load_BMP(const char *path)
+{
+ GP_Context *img;
+
+ img = GP_LoadBMP(path, NULL);
+
+ if (img == NULL) {
+ switch (errno) {
+ case ENOSYS:
+ tst_report(0, "Not Implemented");
+ return TST_SKIPPED;
+ default:
+ tst_report(0, "Got %s", strerror(errno));
+ return TST_FAILED;
+ }
+ }
+
+ /*
+ * TODO: check correct data.
+ */
+
+ GP_ContextFree(img);
+
+ return TST_SUCCESS;
+}
+
+/* Basic loading tests */
+
+static int test_load_BMP_1bpp_1x1(void)
+{
+ return test_load_BMP("1bpp-1x1.bmp");
+}
+
+static int test_load_BMP_4bpp_1x1(void)
+{
+ return test_load_BMP("4bpp-1x1.bmp");
+}
+
+static int test_load_BMP_8bpp_1x1(void)
+{
+ return test_load_BMP("8bpp-1x1.bmp");
+}
+
+static int test_load_BMP_24bpp_1x1(void)
+{
+ return test_load_BMP("24bpp-1x1.bmp");
+}
+
+static int test_load_BMP_32bpp_1x1(void)
+{
+ return test_load_BMP("32bpp-1x1.bmp");
+}
+
+static int test_load_BMP_555_1x1(void)
+{
+ return test_load_BMP("555-1x1.bmp");
+}
+
+static int test_load_BMP_565_1x1(void)
+{
+ return test_load_BMP("565-1x1.bmp");
+}
+
+static int test_load_BMP_8bpp_1x64000(void)
+{
+ return test_load_BMP("8bpp-1x64000.bmp");
+}
+
const struct tst_suite tst_suite = {
.suite_name = "Image Loaders testsuite",
.tests = {
@@ -545,7 +613,32 @@ const struct tst_suite tst_suite = {
.flags = TST_TMPDIR | TST_CHECK_MALLOC},
{.name = "JPG Stress", .tst_fn = test_JPG_stress,
.flags = TST_TMPDIR | TST_CHECK_MALLOC},
+
+ /* BPM loader tests */
+ {.name = "BMP Load 1bpp 1x1", .tst_fn = test_load_BMP_1bpp_1x1,
+ .flags = TST_TMPDIR, .res_path = "data/bmp/valid/1bpp-1x1.bmp"},
+
+ {.name = "BMP Load 4bpp 1x1", .tst_fn = test_load_BMP_4bpp_1x1,
+ .flags = TST_TMPDIR, .res_path = "data/bmp/valid/4bpp-1x1.bmp"},
+ {.name = "BMP Load 8bpp 1x1", .tst_fn = test_load_BMP_8bpp_1x1,
+ .flags = TST_TMPDIR, .res_path = "data/bmp/valid/8bpp-1x1.bmp"},
+
+ {.name = "BMP 24bpp 1x1", .tst_fn = test_load_BMP_24bpp_1x1,
+ .flags = TST_TMPDIR, .res_path = "data/bmp/valid/24bpp-1x1.bmp"},
+
+ {.name = "BMP 32bpp 1x1", .tst_fn = test_load_BMP_32bpp_1x1,
+ .flags = TST_TMPDIR, .res_path = "data/bmp/valid/32bpp-1x1.bmp"},
+
+ {.name = "BMP 555 1x1", .tst_fn = test_load_BMP_555_1x1,
+ .flags = TST_TMPDIR, .res_path = "data/bmp/valid/555-1x1.bmp"},
+
+ {.name = "BMP 565 1x1", .tst_fn = test_load_BMP_565_1x1,
+ .flags = TST_TMPDIR, .res_path = "data/bmp/valid/565-1x1.bmp"},
+
+ {.name = "BMP 8bpp 1x64000", .tst_fn = test_load_BMP_8bpp_1x64000,
+ .flags = TST_TMPDIR, .res_path = "data/bmp/valid/8bpp-1x64000.bmp"},
+
{.name = NULL},
}
};
http://repo.or.cz/w/gfxprim.git/commit/b27ea6e7962b7a22dbd9fdf48e9ffe2358c8…
commit b27ea6e7962b7a22dbd9fdf48e9ffe2358c88097
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sat Oct 13 20:06:10 2012 +0200
tests: loaders: Add generator + bmp images.
diff --git a/tests/loaders/data/bmp/README b/tests/loaders/data/bmp/README
new file mode 100644
index 0000000..470df6a
--- /dev/null
+++ b/tests/loaders/data/bmp/README
@@ -0,0 +1,4 @@
+Run the script to regenerate bitmaps.
+
+The script is not python 3 ready
+(although I've fixed most of the problems)
diff --git a/tests/loaders/data/bmp/bitmaps/corrupt/1bpp-no-palette.bmp b/tests/loaders/data/bmp/bitmaps/corrupt/1bpp-no-palette.bmp
new file mode 100644
index 0000000..24f46bd
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/corrupt/1bpp-no-palette.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/corrupt/1bpp-pixeldata-cropped.bmp b/tests/loaders/data/bmp/bitmaps/corrupt/1bpp-pixeldata-cropped.bmp
new file mode 100644
index 0000000..488bd4e
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/corrupt/1bpp-pixeldata-cropped.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/corrupt/24bpp-pixeldata-cropped.bmp b/tests/loaders/data/bmp/bitmaps/corrupt/24bpp-pixeldata-cropped.bmp
new file mode 100644
index 0000000..248bef4
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/corrupt/24bpp-pixeldata-cropped.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/corrupt/32bpp-pixeldata-cropped.bmp b/tests/loaders/data/bmp/bitmaps/corrupt/32bpp-pixeldata-cropped.bmp
new file mode 100644
index 0000000..11a37e0
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/corrupt/32bpp-pixeldata-cropped.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/corrupt/4bpp-no-palette.bmp b/tests/loaders/data/bmp/bitmaps/corrupt/4bpp-no-palette.bmp
new file mode 100644
index 0000000..667ee63
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/corrupt/4bpp-no-palette.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/corrupt/4bpp-pixeldata-cropped.bmp b/tests/loaders/data/bmp/bitmaps/corrupt/4bpp-pixeldata-cropped.bmp
new file mode 100644
index 0000000..ffa50ae
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/corrupt/4bpp-pixeldata-cropped.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/corrupt/555-pixeldata-cropped.bmp b/tests/loaders/data/bmp/bitmaps/corrupt/555-pixeldata-cropped.bmp
new file mode 100644
index 0000000..2d08d35
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/corrupt/555-pixeldata-cropped.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/corrupt/8bpp-colorsimportant-large.bmp b/tests/loaders/data/bmp/bitmaps/corrupt/8bpp-colorsimportant-large.bmp
new file mode 100644
index 0000000..249c090
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/corrupt/8bpp-colorsimportant-large.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/corrupt/8bpp-colorsimportant-negative.bmp b/tests/loaders/data/bmp/bitmaps/corrupt/8bpp-colorsimportant-negative.bmp
new file mode 100644
index 0000000..1dfe0e9
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/corrupt/8bpp-colorsimportant-negative.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/corrupt/8bpp-colorsused-large.bmp b/tests/loaders/data/bmp/bitmaps/corrupt/8bpp-colorsused-large.bmp
new file mode 100644
index 0000000..2a3195b
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/corrupt/8bpp-colorsused-large.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/corrupt/8bpp-colorsused-negative.bmp b/tests/loaders/data/bmp/bitmaps/corrupt/8bpp-colorsused-negative.bmp
new file mode 100644
index 0000000..f8e0fab
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/corrupt/8bpp-colorsused-negative.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/corrupt/8bpp-no-palette.bmp b/tests/loaders/data/bmp/bitmaps/corrupt/8bpp-no-palette.bmp
new file mode 100644
index 0000000..e8eafa4
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/corrupt/8bpp-no-palette.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/corrupt/8bpp-pixeldata-cropped.bmp b/tests/loaders/data/bmp/bitmaps/corrupt/8bpp-pixeldata-cropped.bmp
new file mode 100644
index 0000000..5fcdcba
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/corrupt/8bpp-pixeldata-cropped.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/corrupt/bitdepth-large.bmp b/tests/loaders/data/bmp/bitmaps/corrupt/bitdepth-large.bmp
new file mode 100644
index 0000000..3e4777f
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/corrupt/bitdepth-large.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/corrupt/bitdepth-odd.bmp b/tests/loaders/data/bmp/bitmaps/corrupt/bitdepth-odd.bmp
new file mode 100644
index 0000000..912c845
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/corrupt/bitdepth-odd.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/corrupt/bitdepth-zero.bmp b/tests/loaders/data/bmp/bitmaps/corrupt/bitdepth-zero.bmp
new file mode 100644
index 0000000..fa9a92a
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/corrupt/bitdepth-zero.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/corrupt/colormasks-cropped.bmp b/tests/loaders/data/bmp/bitmaps/corrupt/colormasks-cropped.bmp
new file mode 100644
index 0000000..c11133c
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/corrupt/colormasks-cropped.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/corrupt/colormasks-missing.bmp b/tests/loaders/data/bmp/bitmaps/corrupt/colormasks-missing.bmp
new file mode 100644
index 0000000..228c5c9
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/corrupt/colormasks-missing.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/corrupt/compression-bad-rle4-for-8bpp.bmp b/tests/loaders/data/bmp/bitmaps/corrupt/compression-bad-rle4-for-8bpp.bmp
new file mode 100644
index 0000000..045b861
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/corrupt/compression-bad-rle4-for-8bpp.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/corrupt/compression-bad-rle8-for-4bpp.bmp b/tests/loaders/data/bmp/bitmaps/corrupt/compression-bad-rle8-for-4bpp.bmp
new file mode 100644
index 0000000..03d4cb7
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/corrupt/compression-bad-rle8-for-4bpp.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/corrupt/compression-unknown.bmp b/tests/loaders/data/bmp/bitmaps/corrupt/compression-unknown.bmp
new file mode 100644
index 0000000..3465800
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/corrupt/compression-unknown.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/corrupt/emptyfile.bmp b/tests/loaders/data/bmp/bitmaps/corrupt/emptyfile.bmp
new file mode 100644
index 0000000..e69de29
diff --git a/tests/loaders/data/bmp/bitmaps/corrupt/fileinfoheader-cropped.bmp b/tests/loaders/data/bmp/bitmaps/corrupt/fileinfoheader-cropped.bmp
new file mode 100644
index 0000000..f7ff95e
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/corrupt/fileinfoheader-cropped.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/corrupt/height-zero.bmp b/tests/loaders/data/bmp/bitmaps/corrupt/height-zero.bmp
new file mode 100644
index 0000000..b07834b
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/corrupt/height-zero.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/corrupt/index.html b/tests/loaders/data/bmp/bitmaps/corrupt/index.html
new file mode 100644
index 0000000..e42e718
--- /dev/null
+++ b/tests/loaders/data/bmp/bitmaps/corrupt/index.html
@@ -0,0 +1,444 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+ <head>
+ <title>Directory Listing</title>
+ </head>
+ <body>
+ <table border="1">
+
+ <tr>
+ <th>Filename</th>
+ <th>Description</th>
+ </tr>
+
+ <tr>
+ <td><a href="1bpp-no-palette.bmp">1bpp-no-palette.bmp</a></td>
+ <td>
+ A bitmap that has 1 bit per pixel and no palette.
+ This is technically invalid, but a bitmap processor could default to black and white.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="1bpp-pixeldata-cropped.bmp">1bpp-pixeldata-cropped.bmp</a></td>
+ <td>
+ A 1 bpp bitmap that ends in the middle of the pixel data.
+ This tests that what happens when a call to fread() fails.
+ This bitmap processor should probably process the data that
+ it does have AND display a diagnostic.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="24bpp-pixeldata-cropped.bmp">24bpp-pixeldata-cropped.bmp</a></td>
+ <td>
+ A 24 bpp bitmap that ends in the middle of the pixel data.
+ This tests that what happens when a call to fread() fails.
+ This bitmap processor should probably process the data that
+ it does have AND display a diagnostic.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="32bpp-pixeldata-cropped.bmp">32bpp-pixeldata-cropped.bmp</a></td>
+ <td>
+ A 32 bpp bitmap that ends in the middle of the pixel data.
+ This tests that what happens when a call to fread() fails.
+ This bitmap processor should probably process the data that
+ it does have AND display a diagnostic.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="4bpp-no-palette.bmp">4bpp-no-palette.bmp</a></td>
+ <td>
+ A bitmap that has 4 bit per pixel and no palette.
+ This is an invalid bitmap, but a bitmap processor could use default colors.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="4bpp-pixeldata-cropped.bmp">4bpp-pixeldata-cropped.bmp</a></td>
+ <td>
+ An 4 bpp bitmap that ends in the middle of the pixel data.
+ This tests that what happens when a call to fread() fails.
+ This bitmap processor should probably process the data that
+ it does have AND display a diagnostic.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="555-pixeldata-cropped.bmp">555-pixeldata-cropped.bmp</a></td>
+ <td>
+ A 5-5-5 16 bpp bitmap that ends in the middle of the pixel data.
+ This tests that what happens when a call to fread() fails.
+ This bitmap processor should probably process the data that
+ it does have AND display a diagnostic.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="8bpp-colorsimportant-large.bmp">8bpp-colorsimportant-large.bmp</a></td>
+ <td>
+ An 8 bpp bitmap with five colors, but a very large 'biColorsImportant' field.
+ This is invalid--biColorsImportant shouldn't exceed biColorsUsed.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="8bpp-colorsimportant-negative.bmp">8bpp-colorsimportant-negative.bmp</a></td>
+ <td>
+ An 8 bpp bitmap with a negative 'biColorsImportant' field.
+ This is invalid--biColorsImportant can't be below 0.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="8bpp-colorsused-large.bmp">8bpp-colorsused-large.bmp</a></td>
+ <td>
+ An 8 bpp bitmap with a very large 'biColorsUsed' field.
+ This is invalid--biColorsImportant shouldn't exceed 256.
+ This attempts to trick the bitmap processor into accessing invalid memory.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="8bpp-colorsused-negative.bmp">8bpp-colorsused-negative.bmp</a></td>
+ <td>
+ An 8 bpp bitmap with a negative 'biColorsUsed' field.
+ This is invalid--biColorsImportant can't be below 0.
+ This attempts to trick the bitmap processor into accessing invalid memory.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="8bpp-no-palette.bmp">8bpp-no-palette.bmp</a></td>
+ <td>
+ A bitmap that has 8 bits per pixel and no palette.
+ This is an invalid bitmap, but a bitmap processor could use default colors.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="8bpp-pixeldata-cropped.bmp">8bpp-pixeldata-cropped.bmp</a></td>
+ <td>
+ An 8 bpp bitmap that ends in the middle of the pixel data.
+ This tests that what happens when a call to fread() fails.
+ This bitmap processor should probably process the data that
+ it does have AND display a diagnostic.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="bitdepth-large.bmp">bitdepth-large.bmp</a></td>
+ <td>
+ A bitmap with a 'biBitCount' field in its BMPINFOHEADER that is very large.
+ This attempts to trick the bitmap processor into thinking the bit depth is negative.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="bitdepth-odd.bmp">bitdepth-odd.bmp</a></td>
+ <td>
+ A bitmap with a 'biBitCount' field in its BMPINFOHEADER that is odd.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="bitdepth-zero.bmp">bitdepth-zero.bmp</a></td>
+ <td>
+ A bitmap with a 'biBitCount' field in its BMPINFOHEADER that is 0.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="colormasks-cropped.bmp">colormasks-cropped.bmp</a></td>
+ <td>
+ A BI_BITFIELDS bitmap that is one byte short of having a complete
+ colormask array.
+ This tests that what happens when fread() returns fewer bytes
+ than expected.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="colormasks-missing.bmp">colormasks-missing.bmp</a></td>
+ <td>
+ A BI_BITFIELDS bitmap file that is so short that it doesn't include the
+ colormask array.
+ This tests that what happens when a call to fread() fails.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="compression-bad-rle4-for-8bpp.bmp">compression-bad-rle4-for-8bpp.bmp</a></td>
+ <td>
+ A 4 bpp bitmap with a 'biCompression' field of BI_RLE8.
+ Only 8 bpp bitmaps may use BI_RLE8.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="compression-bad-rle8-for-4bpp.bmp">compression-bad-rle8-for-4bpp.bmp</a></td>
+ <td>
+ An 8 bpp bitmap with a 'biCompression' field of BI_RLE4.
+ Only 4 bpp bitmaps may use BI_RLE4.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="compression-unknown.bmp">compression-unknown.bmp</a></td>
+ <td>
+ A bitmap with an unrecognized 'biCompression' field.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="emptyfile.bmp">emptyfile.bmp</a></td>
+ <td>
+ A zero-byte file.
+ This tests that what happens when the first call to fread() fails.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="fileinfoheader-cropped.bmp">fileinfoheader-cropped.bmp</a></td>
+ <td>
+ A bitmap that is one byte short of having a complete fileinfoheader.
+ This tests that what happens when fread() returns fewer bytes
+ than expected.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="height-zero.bmp">height-zero.bmp</a></td>
+ <td>
+ A bitmap with a 'biHeight' field in its BMPINFOHEADER that is 0.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="infoheader-cropped.bmp">infoheader-cropped.bmp</a></td>
+ <td>
+ A bitmap that is one byte short of having a complete BITMAPINFOHEADER.
+ This tests that what happens when fread() returns fewer bytes
+ than expected.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="infoheader-missing.bmp">infoheader-missing.bmp</a></td>
+ <td>
+ A bitmap file that is so short that it doesn't include a BITMAPINFOHEADER.
+ This tests that what happens when a call to fread() fails.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="infoheadersize-large.bmp">infoheadersize-large.bmp</a></td>
+ <td>
+ A bitmap with a 'biSize' field in its BMPINFOHEADER that is too large.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="infoheadersize-small.bmp">infoheadersize-small.bmp</a></td>
+ <td>
+ A bitmap with a 'biSize' field in its BMPINFOHEADER that is too small.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="infoheadersize-zero.bmp">infoheadersize-zero.bmp</a></td>
+ <td>
+ A bitmap with a 'biSize' field in its BMPINFOHEADER that is 0.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="magicnumber-bad.bmp">magicnumber-bad.bmp</a></td>
+ <td>
+ A bitmap with an invalid magic number (it uses 'Bm' instead of 'BM')
+ A bitmap processor that ignores this field is probably trusting the file extension
+ or doing a case-insensitive compare.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="magicnumber-cropped.bmp">magicnumber-cropped.bmp</a></td>
+ <td>
+ A one byte bitmap that only contains the 'B' of the magic number.
+ This tests that what happens when the first call to fread() returns
+ fewer bytes than expected.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="offbits-large.bmp">offbits-large.bmp</a></td>
+ <td>
+ A bitmap with an 'dwOffBits' field that is larger than the file size.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="offbits-negative.bmp">offbits-negative.bmp</a></td>
+ <td>
+ A bitmap with an 'dwOffBits' field that is -1.
+ This is supposed to be interpreted as an unsigned value, so it will
+ either be understood as a very large (illegal) value,
+ or a negative value (also illegal).
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="offbits-zero.bmp">offbits-zero.bmp</a></td>
+ <td>
+ A bitmap with an 'dwOffBits' field that is 0.
+ A bitmap processor may recover from this by assuming that the pixel data
+ immediately follows the palette.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="palette-cropped.bmp">palette-cropped.bmp</a></td>
+ <td>
+ A bitmap that is one byte short of having a complete palette.
+ This tests that what happens when fread() returns fewer bytes
+ than expected.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="palette-missing.bmp">palette-missing.bmp</a></td>
+ <td>
+ A bitmap file that is so short that it doesn't include the palette.
+ This tests that what happens when a call to fread() fails.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="palette-too-big.bmp">palette-too-big.bmp</a></td>
+ <td>A bitmap that has 1 bit per pixel that has a palette with 5000 colors.</td>
+ </tr>
+
+ <tr>
+ <td><a href="pixeldata-missing.bmp">pixeldata-missing.bmp</a></td>
+ <td>
+ A bitmap file that doesn't include any of the pixel data.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="rle4-absolute-cropped.bmp">rle4-absolute-cropped.bmp</a></td>
+ <td>
+ A simple run-length encoded bitmap that has 4 bits per pixel.
+ The entire bitmap is in 'absolute mode'.
+ The pixel data ends prematurely--in the middle of an absolute
+ escape sequence.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="rle4-delta-cropped.bmp">rle4-delta-cropped.bmp</a></td>
+ <td>
+ A simple run-length encoded bitmap that has 4 bits per pixel.
+ The bitmap uses 'delta escapes'.
+ The file ends in the middle of a delta escape.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="rle4-no-end-of-line-marker.bmp">rle4-no-end-of-line-marker.bmp</a></td>
+ <td>
+ An RLE4 compressed bitmap with no end-of-line sequences.
+ It is unclear if a bitmap processor should implicitly add
+ end-of-line markers when the pixel run the row's width,
+ or if it should ignore all pixel data beyond the row's width.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="rle4-runlength-cropped.bmp">rle4-runlength-cropped.bmp</a></td>
+ <td>
+ A simple run-length encoded bitmap that has 4 bits per pixel.
+ The entire bitmap is in 'encoded mode'.
+ The pixel data ends prematurely--in the middle of an encoded
+ escape sequence.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="rle8-absolute-cropped.bmp">rle8-absolute-cropped.bmp</a></td>
+ <td>
+ A simple run-length encoded bitmap that has 8 bits per pixel.
+ The entire bitmap is in 'absolute mode'.
+ The pixel data ends prematurely--in the middle of an absolute
+ escape sequence.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="rle8-delta-cropped.bmp">rle8-delta-cropped.bmp</a></td>
+ <td>
+ A simple run-length encoded bitmap that has 8 bits per pixel.
+ The bitmap uses 'delta escapes'.
+ The file ends in the middle of a delta escape.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="rle8-deltaleavesimage.bmp">rle8-deltaleavesimage.bmp</a></td>
+ <td>
+ A simple run-length encoded bitmap that has 8 bits per pixel.
+ The bitmap contains 'delta' escape sequences the leave the image.
+ The intent is to trick the processor into accessing invalid memory.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="rle8-no-end-of-line-marker.bmp">rle8-no-end-of-line-marker.bmp</a></td>
+ <td>
+ An RLE8 compressed bitmap with no end-of-line sequences.
+ It is unclear if a bitmap processor should implicitly add
+ end-of-line markers when the pixel run the row's width,
+ or if it should ignore all pixel data beyond the row's width.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="rle8-runlength-cropped.bmp">rle8-runlength-cropped.bmp</a></td>
+ <td>
+ A simple run-length encoded bitmap that has 8 bits per pixel.
+ The entire bitmap is in 'encoded mode'.
+ The pixel data ends prematurely--in the middle of an encoded
+ escape sequence.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="width-negative.bmp">width-negative.bmp</a></td>
+ <td>
+ A bitmap with a negative 'biWidth' field in its BMPINFOHEADER.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="width-times-height-overflow.bmp">width-times-height-overflow.bmp</a></td>
+ <td>
+ A bitmap whose reported width and height cause a 32bit overflow when
+ they are multiplied together.
+ This tries to trick the image processor into allocating a very small
+ buffer that it thinks is very large.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="width-zero.bmp">width-zero.bmp</a></td>
+ <td>
+ A bitmap with a 'biWidth' field in its BMPINFOHEADER that is 0.
+ </td>
+ </tr>
+
+ </table>
+ </body>
+</html>
diff --git a/tests/loaders/data/bmp/bitmaps/corrupt/infoheader-cropped.bmp b/tests/loaders/data/bmp/bitmaps/corrupt/infoheader-cropped.bmp
new file mode 100644
index 0000000..2b35780
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/corrupt/infoheader-cropped.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/corrupt/infoheader-missing.bmp b/tests/loaders/data/bmp/bitmaps/corrupt/infoheader-missing.bmp
new file mode 100644
index 0000000..bcd3d00
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/corrupt/infoheader-missing.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/corrupt/infoheadersize-large.bmp b/tests/loaders/data/bmp/bitmaps/corrupt/infoheadersize-large.bmp
new file mode 100644
index 0000000..80a3892
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/corrupt/infoheadersize-large.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/corrupt/infoheadersize-small.bmp b/tests/loaders/data/bmp/bitmaps/corrupt/infoheadersize-small.bmp
new file mode 100644
index 0000000..f5186f9
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/corrupt/infoheadersize-small.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/corrupt/infoheadersize-zero.bmp b/tests/loaders/data/bmp/bitmaps/corrupt/infoheadersize-zero.bmp
new file mode 100644
index 0000000..bdbcd45
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/corrupt/infoheadersize-zero.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/corrupt/magicnumber-bad.bmp b/tests/loaders/data/bmp/bitmaps/corrupt/magicnumber-bad.bmp
new file mode 100644
index 0000000..82c0cde
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/corrupt/magicnumber-bad.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/corrupt/magicnumber-cropped.bmp b/tests/loaders/data/bmp/bitmaps/corrupt/magicnumber-cropped.bmp
new file mode 100644
index 0000000..7371f47
--- /dev/null
+++ b/tests/loaders/data/bmp/bitmaps/corrupt/magicnumber-cropped.bmp
@@ -0,0 +1 @@
+B
No newline at end of file
diff --git a/tests/loaders/data/bmp/bitmaps/corrupt/offbits-large.bmp b/tests/loaders/data/bmp/bitmaps/corrupt/offbits-large.bmp
new file mode 100644
index 0000000..431701e
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/corrupt/offbits-large.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/corrupt/offbits-negative.bmp b/tests/loaders/data/bmp/bitmaps/corrupt/offbits-negative.bmp
new file mode 100644
index 0000000..26c9a79
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/corrupt/offbits-negative.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/corrupt/offbits-zero.bmp b/tests/loaders/data/bmp/bitmaps/corrupt/offbits-zero.bmp
new file mode 100644
index 0000000..4e05c3e
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/corrupt/offbits-zero.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/corrupt/palette-cropped.bmp b/tests/loaders/data/bmp/bitmaps/corrupt/palette-cropped.bmp
new file mode 100644
index 0000000..6ae6b13
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/corrupt/palette-cropped.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/corrupt/palette-missing.bmp b/tests/loaders/data/bmp/bitmaps/corrupt/palette-missing.bmp
new file mode 100644
index 0000000..e3e73b1
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/corrupt/palette-missing.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/corrupt/palette-too-big.bmp b/tests/loaders/data/bmp/bitmaps/corrupt/palette-too-big.bmp
new file mode 100644
index 0000000..d04a3d3
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/corrupt/palette-too-big.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/corrupt/pixeldata-missing.bmp b/tests/loaders/data/bmp/bitmaps/corrupt/pixeldata-missing.bmp
new file mode 100644
index 0000000..159289f
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/corrupt/pixeldata-missing.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/corrupt/rle4-absolute-cropped.bmp b/tests/loaders/data/bmp/bitmaps/corrupt/rle4-absolute-cropped.bmp
new file mode 100644
index 0000000..4fdfd9b
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/corrupt/rle4-absolute-cropped.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/corrupt/rle4-delta-cropped.bmp b/tests/loaders/data/bmp/bitmaps/corrupt/rle4-delta-cropped.bmp
new file mode 100644
index 0000000..9eefe97
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/corrupt/rle4-delta-cropped.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/corrupt/rle4-no-end-of-line-marker.bmp b/tests/loaders/data/bmp/bitmaps/corrupt/rle4-no-end-of-line-marker.bmp
new file mode 100644
index 0000000..dc3e4d9
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/corrupt/rle4-no-end-of-line-marker.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/corrupt/rle4-runlength-cropped.bmp b/tests/loaders/data/bmp/bitmaps/corrupt/rle4-runlength-cropped.bmp
new file mode 100644
index 0000000..f68d342
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/corrupt/rle4-runlength-cropped.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/corrupt/rle8-absolute-cropped.bmp b/tests/loaders/data/bmp/bitmaps/corrupt/rle8-absolute-cropped.bmp
new file mode 100644
index 0000000..1776407
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/corrupt/rle8-absolute-cropped.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/corrupt/rle8-delta-cropped.bmp b/tests/loaders/data/bmp/bitmaps/corrupt/rle8-delta-cropped.bmp
new file mode 100644
index 0000000..273cb20
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/corrupt/rle8-delta-cropped.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/corrupt/rle8-deltaleavesimage.bmp b/tests/loaders/data/bmp/bitmaps/corrupt/rle8-deltaleavesimage.bmp
new file mode 100644
index 0000000..b531946
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/corrupt/rle8-deltaleavesimage.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/corrupt/rle8-no-end-of-line-marker.bmp b/tests/loaders/data/bmp/bitmaps/corrupt/rle8-no-end-of-line-marker.bmp
new file mode 100644
index 0000000..f6eab23
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/corrupt/rle8-no-end-of-line-marker.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/corrupt/rle8-runlength-cropped.bmp b/tests/loaders/data/bmp/bitmaps/corrupt/rle8-runlength-cropped.bmp
new file mode 100644
index 0000000..4db7a93
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/corrupt/rle8-runlength-cropped.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/corrupt/width-negative.bmp b/tests/loaders/data/bmp/bitmaps/corrupt/width-negative.bmp
new file mode 100644
index 0000000..044b647
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/corrupt/width-negative.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/corrupt/width-times-height-overflow.bmp b/tests/loaders/data/bmp/bitmaps/corrupt/width-times-height-overflow.bmp
new file mode 100644
index 0000000..c4775d9
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/corrupt/width-times-height-overflow.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/corrupt/width-zero.bmp b/tests/loaders/data/bmp/bitmaps/corrupt/width-zero.bmp
new file mode 100644
index 0000000..2e8cb8a
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/corrupt/width-zero.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/questionable/32bpp-0x0.bmp b/tests/loaders/data/bmp/bitmaps/questionable/32bpp-0x0.bmp
new file mode 100644
index 0000000..9e59a47
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/questionable/32bpp-0x0.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/questionable/32bpp-0x240.bmp b/tests/loaders/data/bmp/bitmaps/questionable/32bpp-0x240.bmp
new file mode 100644
index 0000000..ee541ee
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/questionable/32bpp-0x240.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/questionable/32bpp-320x0.bmp b/tests/loaders/data/bmp/bitmaps/questionable/32bpp-320x0.bmp
new file mode 100644
index 0000000..522dfc3
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/questionable/32bpp-320x0.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/questionable/8bpp-pixels-not-in-palette.bmp b/tests/loaders/data/bmp/bitmaps/questionable/8bpp-pixels-not-in-palette.bmp
new file mode 100644
index 0000000..63cc2a3
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/questionable/8bpp-pixels-not-in-palette.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/questionable/filesize-bad.bmp b/tests/loaders/data/bmp/bitmaps/questionable/filesize-bad.bmp
new file mode 100644
index 0000000..610a910
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/questionable/filesize-bad.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/questionable/filesize-zero.bmp b/tests/loaders/data/bmp/bitmaps/questionable/filesize-zero.bmp
new file mode 100644
index 0000000..cfad0ff
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/questionable/filesize-zero.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/questionable/index.html b/tests/loaders/data/bmp/bitmaps/questionable/index.html
new file mode 100644
index 0000000..536805f
--- /dev/null
+++ b/tests/loaders/data/bmp/bitmaps/questionable/index.html
@@ -0,0 +1,197 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+ <head>
+ <title>Directory Listing</title>
+ </head>
+ <body>
+ <table border="1">
+
+ <tr>
+ <th>Filename</th>
+ <th>Description</th>
+ </tr>
+
+ <tr>
+ <td><a href="32bpp-0x0.bmp">32bpp-0x0.bmp</a></td>
+ <td>A bitmap that is 32 bpp uncompressed RGB. The image is 0 pixels wide and 0 pixels high. Even though this is technically valid, most bitmap procesors consider it to be corrupt.</td>
+ </tr>
+
+ <tr>
+ <td><a href="32bpp-0x240.bmp">32bpp-0x240.bmp</a></td>
+ <td>A bitmap that is 32 bpp uncompressed RGB. The image is 0 pixels wide and 240 pixels high. This is a sneaky way of making a 0x0 bitmap. Even though this is technically valid, most bitmap procesors consider it to be corrupt.</td>
+ </tr>
+
+ <tr>
+ <td><a href="32bpp-320x0.bmp">32bpp-320x0.bmp</a></td>
+ <td>A bitmap that is 32 bpp uncompressed RGB. The image is 320 pixels wide and zero pixels high. This is a sneaky way of making a 0x0 bitmap. Even though this is technically valid, most bitmap procesors consider it to be corrupt.</td>
+ </tr>
+
+ <tr>
+ <td><a href="8bpp-pixels-not-in-palette.bmp">8bpp-pixels-not-in-palette.bmp</a></td>
+ <td>
+ A bitmap that is 8 bits per pixel uncompressed RGB.
+ Many of the pixels are indexes that don't exist in the palette.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="filesize-bad.bmp">filesize-bad.bmp</a></td>
+ <td>
+ A bitmap with a filesize that's half of what it should be.
+ Most bitmap processors ignore this field.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="filesize-zero.bmp">filesize-zero.bmp</a></td>
+ <td>
+ A bitmap with an filesize of 0.
+ Most bitmap processors ignore this field.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="pels-per-meter-x-large.bmp">pels-per-meter-x-large.bmp</a></td>
+ <td>
+ An 8 bpp bitmap with a large 'biXPelsPerMeter' field.
+ Most bitmap processors ignore this field, but it is most likely used when
+ printing the image.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="pels-per-meter-x-negative.bmp">pels-per-meter-x-negative.bmp</a></td>
+ <td>
+ An 8 bpp bitmap with a negative 'biXPelsPerMeter' field.
+ Most bitmap processors ignore this field, but it is most likely used when
+ printing the image.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="pels-per-meter-x-zero.bmp">pels-per-meter-x-zero.bmp</a></td>
+ <td>
+ An 8 bpp bitmap with a 'biXPelsPerMeter' field of 0.
+ Most bitmap processors ignore this field, but it is most likely used when
+ printing the image.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="pels-per-meter-y-large.bmp">pels-per-meter-y-large.bmp</a></td>
+ <td>
+ An 8 bpp bitmap with a large 'biYPelsPerMeter' field.
+ Most bitmap processors ignore this field, but it is most likely used when
+ printing the image.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="pels-per-meter-y-negative.bmp">pels-per-meter-y-negative.bmp</a></td>
+ <td>
+ An 8 bpp bitmap with a negative 'biYPelsPerMeter' field.
+ Most bitmap processors ignore this field, but it is most likely used when
+ printing the image.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="pels-per-meter-y-zero.bmp">pels-per-meter-y-zero.bmp</a></td>
+ <td>
+ An 8 bpp bitmap with a 'biYPelsPerMeter' field of 0.
+ Most bitmap processors ignore this field, but it is most likely used when
+ printing the image.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="pixeldata-rle8-toomuch.bmp">pixeldata-rle8-toomuch.bmp</a></td>
+ <td>
+ A simple run-length encoded bitmap that has 8 bits per pixel.
+ The entire bitmap is in 'encoded mode'.
+ It has twice as much data as it should.
+ Since the RLE8 format is mostly a series of drawing directives,
+ this tests that the RLE8 processor keeps memory access within
+ the size of the image.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="pixeldata-toomuch.bmp">pixeldata-toomuch.bmp</a></td>
+ <td>
+ A bitmap with twice as much payload as expected.
+ This attempts to overflow an internal buffer.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="planes-large.bmp">planes-large.bmp</a></td>
+ <td>
+ A bitmap with a 'biPlanes' field in its BMPINFOHEADER that is large.
+ This is an invalid bitmap, but many bitmap processors ignore this field.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="planes-zero.bmp">planes-zero.bmp</a></td>
+ <td>
+ A bitmap with a 'biPlanes' field in its BMPINFOHEADER that is zero.
+ This is an invalid bitmap, but many bitmap processors ignore this field.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="reserved1-bad.bmp">reserved1-bad.bmp</a></td>
+ <td>
+ A bitmap with an 'wReserved1' field that is not 0.
+ This is technically illegal, but most bitmap processors ignore this field.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="reserved2-bad.bmp">reserved2-bad.bmp</a></td>
+ <td>
+ A bitmap with an 'wReserved2' field that is not 0.
+ This is technically illegal, but most bitmap processors ignore this field.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="rle4-height-negative.bmp">rle4-height-negative.bmp</a></td>
+ <td>
+ An RLE4 compressed bitmap with a negative height.
+ This is an illegal bitmap: top-down images cannot be compressed.
+ Still, many bitmap processors can understand it.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="rle4-no-end-of-bitmap-marker.bmp">rle4-no-end-of-bitmap-marker.bmp</a></td>
+ <td>
+ An RLE4 compressed bitmap with no end-of-bitmap sequence.
+ This is techinically invalid, but the bitmap processor should
+ be able to treat the end-of-file as an end-of-bitmap.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="rle8-height-negative.bmp">rle8-height-negative.bmp</a></td>
+ <td>
+ An RLE8 compressed bitmap with a negative height.
+ This is an illegal value: top-down images cannot be compressed.
+ However, many bitmap processors allow top-down compressed images.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="rle8-no-end-of-bitmap-marker.bmp">rle8-no-end-of-bitmap-marker.bmp</a></td>
+ <td>
+ An RLE8 compressed bitmap with no end-of-bitmap sequence.
+ This is techinically invalid, but the bitmap processor should
+ be able to treat the end-of-file as an end-of-bitmap.
+ </td>
+ </tr>
+
+ </table>
+ </body>
+</html>
diff --git a/tests/loaders/data/bmp/bitmaps/questionable/pels-per-meter-x-large.bmp b/tests/loaders/data/bmp/bitmaps/questionable/pels-per-meter-x-large.bmp
new file mode 100644
index 0000000..bccf281
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/questionable/pels-per-meter-x-large.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/questionable/pels-per-meter-x-negative.bmp b/tests/loaders/data/bmp/bitmaps/questionable/pels-per-meter-x-negative.bmp
new file mode 100644
index 0000000..538c440
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/questionable/pels-per-meter-x-negative.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/questionable/pels-per-meter-x-zero.bmp b/tests/loaders/data/bmp/bitmaps/questionable/pels-per-meter-x-zero.bmp
new file mode 100644
index 0000000..3818535
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/questionable/pels-per-meter-x-zero.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/questionable/pels-per-meter-y-large.bmp b/tests/loaders/data/bmp/bitmaps/questionable/pels-per-meter-y-large.bmp
new file mode 100644
index 0000000..09fc3fb
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/questionable/pels-per-meter-y-large.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/questionable/pels-per-meter-y-negative.bmp b/tests/loaders/data/bmp/bitmaps/questionable/pels-per-meter-y-negative.bmp
new file mode 100644
index 0000000..4280173
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/questionable/pels-per-meter-y-negative.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/questionable/pels-per-meter-y-zero.bmp b/tests/loaders/data/bmp/bitmaps/questionable/pels-per-meter-y-zero.bmp
new file mode 100644
index 0000000..7e2a5f4
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/questionable/pels-per-meter-y-zero.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/questionable/pixeldata-rle8-toomuch.bmp b/tests/loaders/data/bmp/bitmaps/questionable/pixeldata-rle8-toomuch.bmp
new file mode 100644
index 0000000..1590b53
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/questionable/pixeldata-rle8-toomuch.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/questionable/pixeldata-toomuch.bmp b/tests/loaders/data/bmp/bitmaps/questionable/pixeldata-toomuch.bmp
new file mode 100644
index 0000000..33256c1
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/questionable/pixeldata-toomuch.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/questionable/planes-large.bmp b/tests/loaders/data/bmp/bitmaps/questionable/planes-large.bmp
new file mode 100644
index 0000000..2c9314e
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/questionable/planes-large.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/questionable/planes-zero.bmp b/tests/loaders/data/bmp/bitmaps/questionable/planes-zero.bmp
new file mode 100644
index 0000000..4709c1a
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/questionable/planes-zero.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/questionable/reserved1-bad.bmp b/tests/loaders/data/bmp/bitmaps/questionable/reserved1-bad.bmp
new file mode 100644
index 0000000..7332e92
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/questionable/reserved1-bad.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/questionable/reserved2-bad.bmp b/tests/loaders/data/bmp/bitmaps/questionable/reserved2-bad.bmp
new file mode 100644
index 0000000..b3de5d8
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/questionable/reserved2-bad.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/questionable/rle4-height-negative.bmp b/tests/loaders/data/bmp/bitmaps/questionable/rle4-height-negative.bmp
new file mode 100644
index 0000000..2c8b2bf
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/questionable/rle4-height-negative.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/questionable/rle4-no-end-of-bitmap-marker.bmp b/tests/loaders/data/bmp/bitmaps/questionable/rle4-no-end-of-bitmap-marker.bmp
new file mode 100644
index 0000000..6f0c703
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/questionable/rle4-no-end-of-bitmap-marker.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/questionable/rle8-height-negative.bmp b/tests/loaders/data/bmp/bitmaps/questionable/rle8-height-negative.bmp
new file mode 100644
index 0000000..4fec6ee
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/questionable/rle8-height-negative.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/questionable/rle8-no-end-of-bitmap-marker.bmp b/tests/loaders/data/bmp/bitmaps/questionable/rle8-no-end-of-bitmap-marker.bmp
new file mode 100644
index 0000000..fcc3a84
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/questionable/rle8-no-end-of-bitmap-marker.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/valid/1bpp-1x1.bmp b/tests/loaders/data/bmp/bitmaps/valid/1bpp-1x1.bmp
new file mode 100644
index 0000000..508b73c
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/valid/1bpp-1x1.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/valid/1bpp-320x240-color.bmp b/tests/loaders/data/bmp/bitmaps/valid/1bpp-320x240-color.bmp
new file mode 100644
index 0000000..282498d
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/valid/1bpp-320x240-color.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/valid/1bpp-320x240-overlappingcolor.bmp b/tests/loaders/data/bmp/bitmaps/valid/1bpp-320x240-overlappingcolor.bmp
new file mode 100644
index 0000000..1b1fe08
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/valid/1bpp-320x240-overlappingcolor.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/valid/1bpp-320x240.bmp b/tests/loaders/data/bmp/bitmaps/valid/1bpp-320x240.bmp
new file mode 100644
index 0000000..19ebb36
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/valid/1bpp-320x240.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/valid/1bpp-321x240.bmp b/tests/loaders/data/bmp/bitmaps/valid/1bpp-321x240.bmp
new file mode 100644
index 0000000..754c829
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/valid/1bpp-321x240.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/valid/1bpp-322x240.bmp b/tests/loaders/data/bmp/bitmaps/valid/1bpp-322x240.bmp
new file mode 100644
index 0000000..caedf4b
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/valid/1bpp-322x240.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/valid/1bpp-323x240.bmp b/tests/loaders/data/bmp/bitmaps/valid/1bpp-323x240.bmp
new file mode 100644
index 0000000..4006075
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/valid/1bpp-323x240.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/valid/1bpp-324x240.bmp b/tests/loaders/data/bmp/bitmaps/valid/1bpp-324x240.bmp
new file mode 100644
index 0000000..d555e8b
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/valid/1bpp-324x240.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/valid/1bpp-325x240.bmp b/tests/loaders/data/bmp/bitmaps/valid/1bpp-325x240.bmp
new file mode 100644
index 0000000..314eec2
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/valid/1bpp-325x240.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/valid/1bpp-326x240.bmp b/tests/loaders/data/bmp/bitmaps/valid/1bpp-326x240.bmp
new file mode 100644
index 0000000..4a077fe
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/valid/1bpp-326x240.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/valid/1bpp-327x240.bmp b/tests/loaders/data/bmp/bitmaps/valid/1bpp-327x240.bmp
new file mode 100644
index 0000000..18eed54
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/valid/1bpp-327x240.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/valid/1bpp-328x240.bmp b/tests/loaders/data/bmp/bitmaps/valid/1bpp-328x240.bmp
new file mode 100644
index 0000000..94c6fa4
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/valid/1bpp-328x240.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/valid/1bpp-329x240.bmp b/tests/loaders/data/bmp/bitmaps/valid/1bpp-329x240.bmp
new file mode 100644
index 0000000..7486b3b
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/valid/1bpp-329x240.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/valid/1bpp-330x240.bmp b/tests/loaders/data/bmp/bitmaps/valid/1bpp-330x240.bmp
new file mode 100644
index 0000000..cabb99f
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/valid/1bpp-330x240.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/valid/1bpp-331x240.bmp b/tests/loaders/data/bmp/bitmaps/valid/1bpp-331x240.bmp
new file mode 100644
index 0000000..328e619
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/valid/1bpp-331x240.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/valid/1bpp-332x240.bmp b/tests/loaders/data/bmp/bitmaps/valid/1bpp-332x240.bmp
new file mode 100644
index 0000000..de3c493
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/valid/1bpp-332x240.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/valid/1bpp-333x240.bmp b/tests/loaders/data/bmp/bitmaps/valid/1bpp-333x240.bmp
new file mode 100644
index 0000000..a17ba37
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/valid/1bpp-333x240.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/valid/1bpp-334x240.bmp b/tests/loaders/data/bmp/bitmaps/valid/1bpp-334x240.bmp
new file mode 100644
index 0000000..c330ffc
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/valid/1bpp-334x240.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/valid/1bpp-335x240.bmp b/tests/loaders/data/bmp/bitmaps/valid/1bpp-335x240.bmp
new file mode 100644
index 0000000..457533c
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/valid/1bpp-335x240.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/valid/1bpp-topdown-320x240.bmp b/tests/loaders/data/bmp/bitmaps/valid/1bpp-topdown-320x240.bmp
new file mode 100644
index 0000000..605f292
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/valid/1bpp-topdown-320x240.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/valid/24bpp-1x1.bmp b/tests/loaders/data/bmp/bitmaps/valid/24bpp-1x1.bmp
new file mode 100644
index 0000000..fa6c104
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/valid/24bpp-1x1.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/valid/24bpp-320x240.bmp b/tests/loaders/data/bmp/bitmaps/valid/24bpp-320x240.bmp
new file mode 100644
index 0000000..9d4a983
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/valid/24bpp-320x240.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/valid/24bpp-321x240.bmp b/tests/loaders/data/bmp/bitmaps/valid/24bpp-321x240.bmp
new file mode 100644
index 0000000..9925d29
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/valid/24bpp-321x240.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/valid/24bpp-322x240.bmp b/tests/loaders/data/bmp/bitmaps/valid/24bpp-322x240.bmp
new file mode 100644
index 0000000..10616fe
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/valid/24bpp-322x240.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/valid/24bpp-323x240.bmp b/tests/loaders/data/bmp/bitmaps/valid/24bpp-323x240.bmp
new file mode 100644
index 0000000..c5138f4
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/valid/24bpp-323x240.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/valid/24bpp-imagesize-zero.bmp b/tests/loaders/data/bmp/bitmaps/valid/24bpp-imagesize-zero.bmp
new file mode 100644
index 0000000..578eaf5
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/valid/24bpp-imagesize-zero.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/valid/24bpp-topdown-320x240.bmp b/tests/loaders/data/bmp/bitmaps/valid/24bpp-topdown-320x240.bmp
new file mode 100644
index 0000000..b50375e
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/valid/24bpp-topdown-320x240.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/valid/32bpp-101110-320x240.bmp b/tests/loaders/data/bmp/bitmaps/valid/32bpp-101110-320x240.bmp
new file mode 100644
index 0000000..b75d4db
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/valid/32bpp-101110-320x240.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/valid/32bpp-1x1.bmp b/tests/loaders/data/bmp/bitmaps/valid/32bpp-1x1.bmp
new file mode 100644
index 0000000..d1b33e4
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/valid/32bpp-1x1.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/valid/32bpp-320x240.bmp b/tests/loaders/data/bmp/bitmaps/valid/32bpp-320x240.bmp
new file mode 100644
index 0000000..9b63573
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/valid/32bpp-320x240.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/valid/32bpp-888-optimalpalette-320x240.bmp b/tests/loaders/data/bmp/bitmaps/valid/32bpp-888-optimalpalette-320x240.bmp
new file mode 100644
index 0000000..77deadb
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/valid/32bpp-888-optimalpalette-320x240.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/valid/32bpp-optimalpalette-320x240.bmp b/tests/loaders/data/bmp/bitmaps/valid/32bpp-optimalpalette-320x240.bmp
new file mode 100644
index 0000000..4f5929a
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/valid/32bpp-optimalpalette-320x240.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/valid/32bpp-topdown-320x240.bmp b/tests/loaders/data/bmp/bitmaps/valid/32bpp-topdown-320x240.bmp
new file mode 100644
index 0000000..e8a388c
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/valid/32bpp-topdown-320x240.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/valid/4bpp-1x1.bmp b/tests/loaders/data/bmp/bitmaps/valid/4bpp-1x1.bmp
new file mode 100644
index 0000000..edc72d8
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/valid/4bpp-1x1.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/valid/4bpp-320x240.bmp b/tests/loaders/data/bmp/bitmaps/valid/4bpp-320x240.bmp
new file mode 100644
index 0000000..9f95294
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/valid/4bpp-320x240.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/valid/4bpp-321x240.bmp b/tests/loaders/data/bmp/bitmaps/valid/4bpp-321x240.bmp
new file mode 100644
index 0000000..9afaa79
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/valid/4bpp-321x240.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/valid/4bpp-322x240.bmp b/tests/loaders/data/bmp/bitmaps/valid/4bpp-322x240.bmp
new file mode 100644
index 0000000..dc84792
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/valid/4bpp-322x240.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/valid/4bpp-323x240.bmp b/tests/loaders/data/bmp/bitmaps/valid/4bpp-323x240.bmp
new file mode 100644
index 0000000..158fcab
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/valid/4bpp-323x240.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/valid/4bpp-324x240.bmp b/tests/loaders/data/bmp/bitmaps/valid/4bpp-324x240.bmp
new file mode 100644
index 0000000..b5416d5
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/valid/4bpp-324x240.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/valid/4bpp-325x240.bmp b/tests/loaders/data/bmp/bitmaps/valid/4bpp-325x240.bmp
new file mode 100644
index 0000000..b768df9
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/valid/4bpp-325x240.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/valid/4bpp-326x240.bmp b/tests/loaders/data/bmp/bitmaps/valid/4bpp-326x240.bmp
new file mode 100644
index 0000000..1dd42b7
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/valid/4bpp-326x240.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/valid/4bpp-327x240.bmp b/tests/loaders/data/bmp/bitmaps/valid/4bpp-327x240.bmp
new file mode 100644
index 0000000..1bc4613
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/valid/4bpp-327x240.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/valid/4bpp-topdown-320x240.bmp b/tests/loaders/data/bmp/bitmaps/valid/4bpp-topdown-320x240.bmp
new file mode 100644
index 0000000..6ddbad0
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/valid/4bpp-topdown-320x240.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/valid/555-1x1.bmp b/tests/loaders/data/bmp/bitmaps/valid/555-1x1.bmp
new file mode 100644
index 0000000..b85d03c
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/valid/555-1x1.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/valid/555-320x240.bmp b/tests/loaders/data/bmp/bitmaps/valid/555-320x240.bmp
new file mode 100644
index 0000000..3696dd3
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/valid/555-320x240.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/valid/555-321x240.bmp b/tests/loaders/data/bmp/bitmaps/valid/555-321x240.bmp
new file mode 100644
index 0000000..f03b839
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/valid/555-321x240.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/valid/565-1x1.bmp b/tests/loaders/data/bmp/bitmaps/valid/565-1x1.bmp
new file mode 100644
index 0000000..cb669e3
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/valid/565-1x1.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/valid/565-320x240-topdown.bmp b/tests/loaders/data/bmp/bitmaps/valid/565-320x240-topdown.bmp
new file mode 100644
index 0000000..e12ab81
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/valid/565-320x240-topdown.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/valid/565-320x240.bmp b/tests/loaders/data/bmp/bitmaps/valid/565-320x240.bmp
new file mode 100644
index 0000000..1ac488e
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/valid/565-320x240.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/valid/565-321x240-topdown.bmp b/tests/loaders/data/bmp/bitmaps/valid/565-321x240-topdown.bmp
new file mode 100644
index 0000000..1b1d482
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/valid/565-321x240-topdown.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/valid/565-321x240.bmp b/tests/loaders/data/bmp/bitmaps/valid/565-321x240.bmp
new file mode 100644
index 0000000..d60b99a
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/valid/565-321x240.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/valid/565-322x240-topdown.bmp b/tests/loaders/data/bmp/bitmaps/valid/565-322x240-topdown.bmp
new file mode 100644
index 0000000..060a969
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/valid/565-322x240-topdown.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/valid/565-322x240.bmp b/tests/loaders/data/bmp/bitmaps/valid/565-322x240.bmp
new file mode 100644
index 0000000..7555072
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/valid/565-322x240.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/valid/8bpp-1x1.bmp b/tests/loaders/data/bmp/bitmaps/valid/8bpp-1x1.bmp
new file mode 100644
index 0000000..27ec19a
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/valid/8bpp-1x1.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/valid/8bpp-1x64000.bmp b/tests/loaders/data/bmp/bitmaps/valid/8bpp-1x64000.bmp
new file mode 100644
index 0000000..47ce803
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/valid/8bpp-1x64000.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/valid/8bpp-320x240.bmp b/tests/loaders/data/bmp/bitmaps/valid/8bpp-320x240.bmp
new file mode 100644
index 0000000..0b4d52c
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/valid/8bpp-320x240.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/valid/8bpp-321x240.bmp b/tests/loaders/data/bmp/bitmaps/valid/8bpp-321x240.bmp
new file mode 100644
index 0000000..e3157dd
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/valid/8bpp-321x240.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/valid/8bpp-322x240.bmp b/tests/loaders/data/bmp/bitmaps/valid/8bpp-322x240.bmp
new file mode 100644
index 0000000..dc8774a
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/valid/8bpp-322x240.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/valid/8bpp-323x240.bmp b/tests/loaders/data/bmp/bitmaps/valid/8bpp-323x240.bmp
new file mode 100644
index 0000000..6daae0b
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/valid/8bpp-323x240.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/valid/8bpp-colorsimportant-two.bmp b/tests/loaders/data/bmp/bitmaps/valid/8bpp-colorsimportant-two.bmp
new file mode 100644
index 0000000..dc8005f
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/valid/8bpp-colorsimportant-two.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/valid/8bpp-colorsused-zero.bmp b/tests/loaders/data/bmp/bitmaps/valid/8bpp-colorsused-zero.bmp
new file mode 100644
index 0000000..b40ba16
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/valid/8bpp-colorsused-zero.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/valid/8bpp-topdown-320x240.bmp b/tests/loaders/data/bmp/bitmaps/valid/8bpp-topdown-320x240.bmp
new file mode 100644
index 0000000..27d40fd
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/valid/8bpp-topdown-320x240.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/valid/index.html b/tests/loaders/data/bmp/bitmaps/valid/index.html
new file mode 100644
index 0000000..94674e1
--- /dev/null
+++ b/tests/loaders/data/bmp/bitmaps/valid/index.html
@@ -0,0 +1,421 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+ <head>
+ <title>Directory Listing</title>
+ </head>
+ <body>
+ <table border="1">
+
+ <tr>
+ <th>Filename</th>
+ <th>Description</th>
+ </tr>
+
+ <tr>
+ <td><a href="1bpp-1x1.bmp">1bpp-1x1.bmp</a></td>
+ <td>A bitmap that has 1 bit per pixel. The image is a single black pixel.</td>
+ </tr>
+
+ <tr>
+ <td><a href="1bpp-320x240-color.bmp">1bpp-320x240-color.bmp</a></td>
+ <td>A bitmap that has 1 bit per pixel and a color palette.</td>
+ </tr>
+
+ <tr>
+ <td><a href="1bpp-320x240-overlappingcolor.bmp">1bpp-320x240-overlappingcolor.bmp</a></td>
+ <td>A bitmap that has 1 bit per pixel and a color palette with colors that overlap.</td>
+ </tr>
+
+ <tr>
+ <td><a href="1bpp-320x240.bmp">1bpp-320x240.bmp</a></td>
+ <td>A bitmap that has 1 bit per pixel. Each scanline has 0 bits of padding.</td>
+ </tr>
+
+ <tr>
+ <td><a href="1bpp-321x240.bmp">1bpp-321x240.bmp</a></td>
+ <td>A bitmap that has 1 bit per pixel. Each scanline has 1 bits of padding.</td>
+ </tr>
+
+ <tr>
+ <td><a href="1bpp-322x240.bmp">1bpp-322x240.bmp</a></td>
+ <td>A bitmap that has 1 bit per pixel. Each scanline has 2 bits of padding.</td>
+ </tr>
+
+ <tr>
+ <td><a href="1bpp-323x240.bmp">1bpp-323x240.bmp</a></td>
+ <td>A bitmap that has 1 bit per pixel. Each scanline has 3 bits of padding.</td>
+ </tr>
+
+ <tr>
+ <td><a href="1bpp-324x240.bmp">1bpp-324x240.bmp</a></td>
+ <td>A bitmap that has 1 bit per pixel. Each scanline has 4 bits of padding.</td>
+ </tr>
+
+ <tr>
+ <td><a href="1bpp-325x240.bmp">1bpp-325x240.bmp</a></td>
+ <td>A bitmap that has 1 bit per pixel. Each scanline has 5 bits of padding.</td>
+ </tr>
+
+ <tr>
+ <td><a href="1bpp-326x240.bmp">1bpp-326x240.bmp</a></td>
+ <td>A bitmap that has 1 bit per pixel. Each scanline has 6 bits of padding.</td>
+ </tr>
+
+ <tr>
+ <td><a href="1bpp-327x240.bmp">1bpp-327x240.bmp</a></td>
+ <td>A bitmap that has 1 bit per pixel. Each scanline has 7 bits of padding.</td>
+ </tr>
+
+ <tr>
+ <td><a href="1bpp-328x240.bmp">1bpp-328x240.bmp</a></td>
+ <td>A bitmap that has 1 bit per pixel. Each scanline has 8 bits of padding.</td>
+ </tr>
+
+ <tr>
+ <td><a href="1bpp-329x240.bmp">1bpp-329x240.bmp</a></td>
+ <td>A bitmap that has 1 bit per pixel. Each scanline has 9 bits of padding.</td>
+ </tr>
+
+ <tr>
+ <td><a href="1bpp-330x240.bmp">1bpp-330x240.bmp</a></td>
+ <td>A bitmap that has 1 bit per pixel. Each scanline has 10 bits of padding.</td>
+ </tr>
+
+ <tr>
+ <td><a href="1bpp-331x240.bmp">1bpp-331x240.bmp</a></td>
+ <td>A bitmap that has 1 bit per pixel. Each scanline has 11 bits of padding.</td>
+ </tr>
+
+ <tr>
+ <td><a href="1bpp-332x240.bmp">1bpp-332x240.bmp</a></td>
+ <td>A bitmap that has 1 bit per pixel. Each scanline has 12 bits of padding.</td>
+ </tr>
+
+ <tr>
+ <td><a href="1bpp-333x240.bmp">1bpp-333x240.bmp</a></td>
+ <td>A bitmap that has 1 bit per pixel. Each scanline has 13 bits of padding.</td>
+ </tr>
+
+ <tr>
+ <td><a href="1bpp-334x240.bmp">1bpp-334x240.bmp</a></td>
+ <td>A bitmap that has 1 bit per pixel. Each scanline has 14 bits of padding.</td>
+ </tr>
+
+ <tr>
+ <td><a href="1bpp-335x240.bmp">1bpp-335x240.bmp</a></td>
+ <td>A bitmap that has 1 bit per pixel. Each scanline has 15 bits of padding.</td>
+ </tr>
+
+ <tr>
+ <td><a href="1bpp-topdown-320x240.bmp">1bpp-topdown-320x240.bmp</a></td>
+ <td>A 'top down' uncompressed RGB bitmap that has 1 bit per pixel.</td>
+ </tr>
+
+ <tr>
+ <td><a href="24bpp-1x1.bmp">24bpp-1x1.bmp</a></td>
+ <td>An uncompressed bitmap with 24 bits per pixel. The image is a single blue pixel.</td>
+ </tr>
+
+ <tr>
+ <td><a href="24bpp-320x240.bmp">24bpp-320x240.bmp</a></td>
+ <td>An uncompressed bitmap with 24 bits per pixel. Each scanline has 0 bytes of padding.</td>
+ </tr>
+
+ <tr>
+ <td><a href="24bpp-321x240.bmp">24bpp-321x240.bmp</a></td>
+ <td>An uncompressed bitmap with 24 bits per pixel. Each scanline has 0 bytes of padding.</td>
+ </tr>
+
+ <tr>
+ <td><a href="24bpp-322x240.bmp">24bpp-322x240.bmp</a></td>
+ <td>An uncompressed bitmap with 24 bits per pixel. Each scanline has 0 bytes of padding.</td>
+ </tr>
+
+ <tr>
+ <td><a href="24bpp-323x240.bmp">24bpp-323x240.bmp</a></td>
+ <td>An uncompressed bitmap with 24 bits per pixel. Each scanline has 1 bytes of padding.</td>
+ </tr>
+
+ <tr>
+ <td><a href="24bpp-imagesize-zero.bmp">24bpp-imagesize-zero.bmp</a></td>
+ <td>
+ An uncompressed RGB bitmaps that has 24 bits-per-pixel.
+ The bitmap has a biSizeImage field of 0.
+ The bitmap specification allows the biSizeImage field to be zero
+ for uncompressed images.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="24bpp-topdown-320x240.bmp">24bpp-topdown-320x240.bmp</a></td>
+ <td>A 'top down' bitmap that has 24 bits per pixel.</td>
+ </tr>
+
+ <tr>
+ <td><a href="32bpp-101110-320x240.bmp">32bpp-101110-320x240.bmp</a></td>
+ <td>
+ A bitmap that is 32 bpp uncompressed RGB.
+ This bitmap uses 10-11-10 RGB color masks.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="32bpp-1x1.bmp">32bpp-1x1.bmp</a></td>
+ <td>A bitmap that is 32 bpp uncompressed RGB. The image is a single blue pixel.</td>
+ </tr>
+
+ <tr>
+ <td><a href="32bpp-320x240.bmp">32bpp-320x240.bmp</a></td>
+ <td>A bitmap that is 32 bpp uncompressed RGB.</td>
+ </tr>
+
+ <tr>
+ <td><a href="32bpp-888-optimalpalette-320x240.bmp">32bpp-888-optimalpalette-320x240.bmp</a></td>
+ <td>
+ A bitmap that is 32 bpp uncompressed RGB.
+ This bitmap has three DWORD color masks, followed by an 'optimal color palette',
+ which is used for optimizing colors on palette-based devices.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="32bpp-optimalpalette-320x240.bmp">32bpp-optimalpalette-320x240.bmp</a></td>
+ <td>
+ A bitmap that is 32 bpp uncompressed RGB.
+ This bitmap has an 'optimal color palette', which is used for optimizing colors on
+ palette-based devices, but does NOT have any color masks.
+ It's unclear to me if this is well-formed or not.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="32bpp-topdown-320x240.bmp">32bpp-topdown-320x240.bmp</a></td>
+ <td>A 'top down' uncompressed RGB bitmap that has 32 bits per pixel.</td>
+ </tr>
+
+ <tr>
+ <td><a href="4bpp-1x1.bmp">4bpp-1x1.bmp</a></td>
+ <td>An uncompressed bitmap that has 4 bits per pixel. The image is a single blue pixel.</td>
+ </tr>
+
+ <tr>
+ <td><a href="4bpp-320x240.bmp">4bpp-320x240.bmp</a></td>
+ <td>An uncompressed bitmap that has 4 bits per pixel. Each scanline has 0 nibbles of padding.</td>
+ </tr>
+
+ <tr>
+ <td><a href="4bpp-321x240.bmp">4bpp-321x240.bmp</a></td>
+ <td>An uncompressed bitmap that has 4 bits per pixel. Each scanline has 1 nibbles of padding.</td>
+ </tr>
+
+ <tr>
+ <td><a href="4bpp-322x240.bmp">4bpp-322x240.bmp</a></td>
+ <td>An uncompressed bitmap that has 4 bits per pixel. Each scanline has 2 nibbles of padding.</td>
+ </tr>
+
+ <tr>
+ <td><a href="4bpp-323x240.bmp">4bpp-323x240.bmp</a></td>
+ <td>An uncompressed bitmap that has 4 bits per pixel. Each scanline has 3 nibbles of padding.</td>
+ </tr>
+
+ <tr>
+ <td><a href="4bpp-324x240.bmp">4bpp-324x240.bmp</a></td>
+ <td>An uncompressed bitmap that has 4 bits per pixel. Each scanline has 4 nibbles of padding.</td>
+ </tr>
+
+ <tr>
+ <td><a href="4bpp-325x240.bmp">4bpp-325x240.bmp</a></td>
+ <td>An uncompressed bitmap that has 4 bits per pixel. Each scanline has 5 nibbles of padding.</td>
+ </tr>
+
+ <tr>
+ <td><a href="4bpp-326x240.bmp">4bpp-326x240.bmp</a></td>
+ <td>An uncompressed bitmap that has 4 bits per pixel. Each scanline has 6 nibbles of padding.</td>
+ </tr>
+
+ <tr>
+ <td><a href="4bpp-327x240.bmp">4bpp-327x240.bmp</a></td>
+ <td>An uncompressed bitmap that has 4 bits per pixel. Each scanline has 7 nibbles of padding.</td>
+ </tr>
+
+ <tr>
+ <td><a href="4bpp-topdown-320x240.bmp">4bpp-topdown-320x240.bmp</a></td>
+ <td>A 'top down' uncompressed RGB bitmap that has 4 bits per pixel.</td>
+ </tr>
+
+ <tr>
+ <td><a href="555-1x1.bmp">555-1x1.bmp</a></td>
+ <td>A bitmap that is 5-5-5 uncompressed RGB The image is a single blue pixel.</td>
+ </tr>
+
+ <tr>
+ <td><a href="555-320x240.bmp">555-320x240.bmp</a></td>
+ <td>A bitmap that is 5-5-5 uncompressed RGB Each scanline has 0 bytes of padding.</td>
+ </tr>
+
+ <tr>
+ <td><a href="555-321x240.bmp">555-321x240.bmp</a></td>
+ <td>A bitmap that is 5-5-5 uncompressed RGB Each scanline has 0 bytes of padding.</td>
+ </tr>
+
+ <tr>
+ <td><a href="565-1x1.bmp">565-1x1.bmp</a></td>
+ <td>A bitmap that is 5-6-5 uncompressed RGB The image is a single blue pixel.</td>
+ </tr>
+
+ <tr>
+ <td><a href="565-320x240-topdown.bmp">565-320x240-topdown.bmp</a></td>
+ <td>A 'top down' bitmap that is 5-6-5 uncompressed RGB. Each scanline has 0 bytes of padding.</td>
+ </tr>
+
+ <tr>
+ <td><a href="565-320x240.bmp">565-320x240.bmp</a></td>
+ <td>A bitmap that is 5-6-5 uncompressed RGB Each scanline has 0 bytes of padding.</td>
+ </tr>
+
+ <tr>
+ <td><a href="565-321x240-topdown.bmp">565-321x240-topdown.bmp</a></td>
+ <td>A 'top down' bitmap that is 5-6-5 uncompressed RGB. Each scanline has 0 bytes of padding.</td>
+ </tr>
+
+ <tr>
+ <td><a href="565-321x240.bmp">565-321x240.bmp</a></td>
+ <td>A bitmap that is 5-6-5 uncompressed RGB Each scanline has 0 bytes of padding.</td>
+ </tr>
+
+ <tr>
+ <td><a href="565-322x240-topdown.bmp">565-322x240-topdown.bmp</a></td>
+ <td>A 'top down' bitmap that is 5-6-5 uncompressed RGB. Each scanline has 1 bytes of padding.</td>
+ </tr>
+
+ <tr>
+ <td><a href="565-322x240.bmp">565-322x240.bmp</a></td>
+ <td>A bitmap that is 5-6-5 uncompressed RGB Each scanline has 1 bytes of padding.</td>
+ </tr>
+
+ <tr>
+ <td><a href="8bpp-1x1.bmp">8bpp-1x1.bmp</a></td>
+ <td>An uncompressed RGB bitmap that has 8 bits per pixel. The image is a single blue pixel.</td>
+ </tr>
+
+ <tr>
+ <td><a href="8bpp-1x64000.bmp">8bpp-1x64000.bmp</a></td>
+ <td>An uncompressed RGB bitmap that has 8 bits per pixel. The image is a very long, blue vertical line.</td>
+ </tr>
+
+ <tr>
+ <td><a href="8bpp-320x240.bmp">8bpp-320x240.bmp</a></td>
+ <td>An uncompressed RGB bitmap that has 8 bits per pixel. Each scanline has 0 bytes of padding.</td>
+ </tr>
+
+ <tr>
+ <td><a href="8bpp-321x240.bmp">8bpp-321x240.bmp</a></td>
+ <td>An uncompressed RGB bitmap that has 8 bits per pixel. Each scanline has 1 bytes of padding.</td>
+ </tr>
+
+ <tr>
+ <td><a href="8bpp-322x240.bmp">8bpp-322x240.bmp</a></td>
+ <td>An uncompressed RGB bitmap that has 8 bits per pixel. Each scanline has 2 bytes of padding.</td>
+ </tr>
+
+ <tr>
+ <td><a href="8bpp-323x240.bmp">8bpp-323x240.bmp</a></td>
+ <td>An uncompressed RGB bitmap that has 8 bits per pixel. Each scanline has 3 bytes of padding.</td>
+ </tr>
+
+ <tr>
+ <td><a href="8bpp-colorsimportant-two.bmp">8bpp-colorsimportant-two.bmp</a></td>
+ <td>
+ An 8 bpp bitmap with five colors, but a 'biColorsImportant' field of 2.
+ This indicates that only black and white are important.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="8bpp-colorsused-zero.bmp">8bpp-colorsused-zero.bmp</a></td>
+ <td>
+ An 8 bpp bitmap with a 'biColorsUsed' field of 0.
+ This indicates that the palette contains 256 entries, which it does.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="8bpp-topdown-320x240.bmp">8bpp-topdown-320x240.bmp</a></td>
+ <td>A 'top down' uncompressed RGB bitmap that has 8 bits per pixel.</td>
+ </tr>
+
+ <tr>
+ <td><a href="rle4-absolute-320x240.bmp">rle4-absolute-320x240.bmp</a></td>
+ <td>
+ A run-length encoded bitmap that has 4 bits per pixel.
+ The entire bitmap is in 'absolute mode'.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="rle4-alternate-320x240.bmp">rle4-alternate-320x240.bmp</a></td>
+ <td>
+ A simple run-length encoded bitmap that has 4 bits per pixel.
+ The entire bitmap is in 'encoded mode'.
+ The runs encode alternating pixel colors, such as dithering would create.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="rle4-delta-320x240.bmp">rle4-delta-320x240.bmp</a></td>
+ <td>
+ A simple run-length encoded bitmap that has 4 bits per pixel.
+ The bitmap uses 'delta escapes'.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="rle4-encoded-320x240.bmp">rle4-encoded-320x240.bmp</a></td>
+ <td>
+ A simple run-length encoded bitmap that has 4 bits per pixel.
+ The entire bitmap is in 'encoded mode'.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="rle8-64000x1.bmp">rle8-64000x1.bmp</a></td>
+ <td>
+ A simple run-length encoded bitmap that has 8 bits per pixel.
+ The entire bitmap is in 'encoded mode'.
+ The image is a very long red, green, and blue horizontal line.</td>
+ </tr>
+
+ <tr>
+ <td><a href="rle8-absolute-320x240.bmp">rle8-absolute-320x240.bmp</a></td>
+ <td>
+ A run-length encoded bitmap that has 8 bits per pixel.
+ The entire bitmap is in 'absolute mode'.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="rle8-blank-160x120.bmp">rle8-blank-160x120.bmp</a></td>
+ <td>
+ A simple run-length encoded bitmap consists of just an end-of-bitmap marker.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="rle8-delta-320x240.bmp">rle8-delta-320x240.bmp</a></td>
+ <td>
+ A simple run-length encoded bitmap that has 8 bits per pixel.
+ The bitmap uses 'delta escapes'.
+ </td>
+ </tr>
+
+ <tr>
+ <td><a href="rle8-encoded-320x240.bmp">rle8-encoded-320x240.bmp</a></td>
+ <td>
+ A simple run-length encoded bitmap that has 8 bits per pixel.
+ The entire bitmap is in 'encoded mode'.
+ </td>
+ </tr>
+
+ </table>
+ </body>
+</html>
diff --git a/tests/loaders/data/bmp/bitmaps/valid/rle4-absolute-320x240.bmp b/tests/loaders/data/bmp/bitmaps/valid/rle4-absolute-320x240.bmp
new file mode 100644
index 0000000..a08745f
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/valid/rle4-absolute-320x240.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/valid/rle4-alternate-320x240.bmp b/tests/loaders/data/bmp/bitmaps/valid/rle4-alternate-320x240.bmp
new file mode 100644
index 0000000..51eda52
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/valid/rle4-alternate-320x240.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/valid/rle4-delta-320x240.bmp b/tests/loaders/data/bmp/bitmaps/valid/rle4-delta-320x240.bmp
new file mode 100644
index 0000000..78a0927
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/valid/rle4-delta-320x240.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/valid/rle4-encoded-320x240.bmp b/tests/loaders/data/bmp/bitmaps/valid/rle4-encoded-320x240.bmp
new file mode 100644
index 0000000..2848dc0
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/valid/rle4-encoded-320x240.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/valid/rle8-64000x1.bmp b/tests/loaders/data/bmp/bitmaps/valid/rle8-64000x1.bmp
new file mode 100644
index 0000000..6ded0a3
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/valid/rle8-64000x1.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/valid/rle8-absolute-320x240.bmp b/tests/loaders/data/bmp/bitmaps/valid/rle8-absolute-320x240.bmp
new file mode 100644
index 0000000..0f65e0b
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/valid/rle8-absolute-320x240.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/valid/rle8-blank-160x120.bmp b/tests/loaders/data/bmp/bitmaps/valid/rle8-blank-160x120.bmp
new file mode 100644
index 0000000..ca8736f
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/valid/rle8-blank-160x120.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/valid/rle8-delta-320x240.bmp b/tests/loaders/data/bmp/bitmaps/valid/rle8-delta-320x240.bmp
new file mode 100644
index 0000000..8007c55
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/valid/rle8-delta-320x240.bmp differ
diff --git a/tests/loaders/data/bmp/bitmaps/valid/rle8-encoded-320x240.bmp b/tests/loaders/data/bmp/bitmaps/valid/rle8-encoded-320x240.bmp
new file mode 100644
index 0000000..15e6313
Binary files /dev/null and b/tests/loaders/data/bmp/bitmaps/valid/rle8-encoded-320x240.bmp differ
diff --git a/tests/loaders/data/bmp/bmptestsuite.py b/tests/loaders/data/bmp/bmptestsuite.py
new file mode 100644
index 0000000..9997fcd
--- /dev/null
+++ b/tests/loaders/data/bmp/bmptestsuite.py
@@ -0,0 +1,3639 @@
+#!/usr/bin/env python
+#
+# Heavily based on http://sourceforge.net/projects/bmptestsuite/
+# by David Costanzo
+#
+# Redistributed under GPLv2
+#
+# Copyright (C) 2012 Cyril Hrubis <metan(a)ucw.cz>
+#
+
+import struct
+import os
+import stat
+import errno
+import string
+import sys
+
+def _safe_create_dir(dirname):
+ "Create a directory named dirname, if it doesn't already exist"
+ try:
+ os.stat(dirname)
+
+ except OSError as info:
+ if info.errno == errno.ENOENT:
+ os.mkdir(dirname)
+ else:
+ raise
+
+
+def _safe_unlink(filename):
+ "Remove a file if it exists"
+ try:
+ os.unlink(filename)
+
+ except OSError as info:
+ if info.errno != errno.ENOENT:
+ raise
+
+TOP_LEFT_LOGO = []
+TOP_LEFT_LOGO.append("........................................................")
+TOP_LEFT_LOGO.append("........................................................")
+TOP_LEFT_LOGO.append("...#######..###...####......#.....####..####..#######...")
+TOP_LEFT_LOGO.append("......#....#...#..#...#.....#.....#.....#........#......")
+TOP_LEFT_LOGO.append("......#....#...#..#...#.....#.....#.....#........#......")
+TOP_LEFT_LOGO.append("......#....#...#..####......#.....###...###......#......")
+TOP_LEFT_LOGO.append("......#....#...#..#.........#.....#.....#........#......")
+TOP_LEFT_LOGO.append("......#....#...#..#.........#.....#.....#........#......")
+TOP_LEFT_LOGO.append("......#.....###...#.........####..####..#........#......")
+TOP_LEFT_LOGO.append("........................................................")
+TOP_LEFT_LOGO.append("........................................................")
+
+class bitmap:
+ "The base class for all test bitmaps"
+
+ SIZEOF_FILEINFOHEADER = 14
+
+ # values for Compression
+ BI_RGB = 0
+ BI_RLE8 = 1
+ BI_RLE4 = 2
+ BI_BITFIELDS = 3
+ BI_JPEG = 4
+ BI_PNG = 5
+ BI_ALPHABITFIELDS = 6
+
+ def __init__(self, bits_per_pixel, width, height):
+ self.bits_per_pixel = bits_per_pixel
+ self.width = width
+ self.height = height
+ self.palette = []
+ self.pixeldata = ''
+
+ # methods that make up the FILEINFOHEADER
+ def get_magic_number(self):
+ return b'BM'
+
+ def get_filesize(self):
+ sizeof_fileinfoheader = self.SIZEOF_FILEINFOHEADER
+ sizeof_bitmapinfoheader = self.get_bitmap_info_header_size()
+ sizeof_palette = len(self.get_palette())
+ sizeof_pixeldata = len(self.get_pixeldata())
+
+ return sizeof_fileinfoheader + sizeof_bitmapinfoheader + sizeof_palette + sizeof_pixeldata
+
+ def get_reserved1(self):
+ return 0
+
+ def get_reserved2(self):
+ return 0
+
+ def get_offset_of_bitmap_data(self):
+ sizeof_fileinfoheader = self.SIZEOF_FILEINFOHEADER
+ sizeof_bitmapinfoheader = self.get_bitmap_info_header_size()
+ sizeof_palette = len(self.get_palette())
+
+ return sizeof_fileinfoheader + sizeof_bitmapinfoheader + sizeof_palette
+
+
+ def get_fileinfoheader(self):
+ "Return the packed BMPFILEINFOHEADER structure"
+
+ magic_number = self.get_magic_number()
+ filesize = self.get_filesize()
+ reserved1 = self.get_reserved1()
+ reserved2 = self.get_reserved2()
+ offbits = self.get_offset_of_bitmap_data()
+
+ fileinfoheader = struct.pack(
+ '<2sIHHi',
+ magic_number,
+ filesize,
+ reserved1,
+ reserved2,
+ offbits)
+
+ return fileinfoheader
+
+
+ def get_bitmap_info_header_size(self):
+ return 40
+
+ def get_bits_per_pixel(self):
+ """
+ Return the biBitCount to put into the BITMAPINFOHEADER.
+ This should be 1, 4, 8, or 24.
+ """
+ return self.bits_per_pixel
+
+ def get_width(self):
+ """
+ Return the biWidth to put into the BITMAPINFOHEADER.
+ This is equal to the width of the bitmap, in pixels.
+ """
+ return self.width
+
+ def get_height(self):
+ "Return the height of bitmap to put into the BITMAPINFOHEADER"
+ return self.height
+
+ def get_planes(self):
+ "Return the value of biPlanes in BITMAPINFOHEADER"
+ return 1
+
+ def get_compression(self):
+ "Return the biCompression to put into the BITMAPINFOHEADER"
+ return self.BI_RGB
+
+ def get_image_size(self):
+ "Return the biSizeImage to put into the BITMAPINFOHEADER"
+ return len(self.get_pixeldata())
+
+ def get_pixels_per_meter_x(self):
+ "Return the biXPelsPerMeter to put into the BITMAPINFOHEADER"
+ return 1000
+
+ def get_pixels_per_meter_y(self):
+ "Return the biYPelsPerMeter to put into the BITMAPINFOHEADER"
+ return 1000
+
+ def get_colors_used(self):
+ "Return the biClrUsed to put into the BITMAPINFOHEADER"
+ # assume that we use all colors
+ return len(self.palette)
+
+ def get_colors_important(self):
+ "Return the biClrImportant to put into the BITMAPINFOHEADER"
+ # assume that all colors are important
+ return 0
+
+ def get_bitmapinfoheader(self):
+ "Return the BITMAPINFOHEADER"
+
+ size = self.get_bitmap_info_header_size()
+ width = self.get_width()
+ height = self.get_height()
+ planes = self.get_planes()
+ bits_per_pixel = self.get_bits_per_pixel()
+ compression = self.get_compression()
+ image_size = self.get_image_size()
+ pixels_per_meter_x = self.get_pixels_per_meter_x()
+ pixels_per_meter_y = self.get_pixels_per_meter_y()
+ colors_used = self.get_colors_used()
+ colors_important = self.get_colors_important()
+
+ bitmapinfoheader = struct.pack(
+ '<IiihHIIiiII',
+ size,
+ width,
+ height,
+ planes,
+ bits_per_pixel,
+ compression,
+ image_size,
+ pixels_per_meter_x,
+ pixels_per_meter_y,
+ colors_used,
+ colors_important)
+
+ return bitmapinfoheader
+
+ def get_palette(self):
+ "Return the palette for bit depths <= 8"
+
+ # Generate the packed palette from self.palette
+ # This will be the empty string if self.palette == []
+ pack_string = '<' + 'I' * len(self.palette)
+ pack_params = [pack_string] + self.palette
+
+ palette = struct.pack(pack_string, *self.palette)
+
+ return palette
+
+ def create_pixeldata(self):
+ "Return the pixel data"
+
+ raise 'bitmap.create_pixeldata() should never be called'
+
+ def create_raster(self):
+ "Return the image as a raster"
+
+ raise 'bitmap.create_pixeldata() should never be called'
+
+ def get_pixeldata(self):
+ """
+ Create and cache the pixel data on the first call.
+ Return the cached value on all subsequent calls.
+ """
+
+ if not self.pixeldata:
+ self.pixeldata = self.create_pixeldata()
+
+ return self.pixeldata
+
+
+ def get_scanline_padding_bits(self):
+ "Return how many bits are used to pad each scanline"
+
+ alignment = 32 # All bitmap scanlines are DWORD aligned
+
+ # start with the number of bits in all pixels in a row
+ padding_bits = alignment - (self.width * self.bits_per_pixel) % alignment
+ padding_bits = padding_bits % alignment
+
+ return padding_bits
+
+
+ def apply_top_left_logo(self, image, on_value, off_value):
+ "Draw the TOP_LEFT_LOGO if there's enough room"
+
+ # leave enough space for the 2 pixel border
+ x_offset = 2
+ y_offset = 2
+
+ # only draw the logo if there's enough room
+ if len(TOP_LEFT_LOGO[0]) + x_offset <= self.width:
+ if len(TOP_LEFT_LOGO) + y_offset <= self.height:
+
+ for row in range(0, len(TOP_LEFT_LOGO)):
+ # find the current row from the top of the image,
+ # based on if this is a top-down or a bottom-up raster
+ if (self.get_height() < 0):
+ # top-down image
+ current_row = image[row + y_offset]
+ else:
+ # bottom-up image
+ current_row = image[self.height - 1 - row - y_offset]
+
+
+ # set the pixels to "on" or "off"
+ for col in range(0, len(TOP_LEFT_LOGO[row])):
+ if (TOP_LEFT_LOGO[row][col] == '.'):
+ # change this pixel to black
+ current_row[col + x_offset] = on_value
+ else:
+ # change this pixel to white
+ current_row[col + x_offset] = off_value
+
+
+ def draw_double_border(self, image, outer_value, inner_value):
+ "Draw two single-pixel borders around the image"
+
+ # image must be at least 5 x 5 to draw the border
+ if 5 <= self.height and 5 <= self.width:
+
+ # draw the outer border
+ for col in range(0, self.width):
+ # top border
+ image[0][col] = outer_value
+
+ # bottom border
+ image[self.height - 1][col] = outer_value
+
+ for row in range(0, self.height):
+ # left border
+ image[row][0] = outer_value
+
+ # right border
+ image[row][self.width - 1] = outer_value
+
+
+ # draw the inner border around the image
+ for col in range(1, self.width - 1):
+ # top border
+ image[1][col] = inner_value
+
+ # bottom border
+ image[self.height - 2][col] = inner_value
+
+ for row in range(1, self.height - 1):
+ # left border
+ image[row][1] = inner_value
+
+ # right border
+ image[row][self.width - 2] = inner_value
+
+
+ def write(self, filename):
+ "Write the bitmap out to a file"
+
+ _safe_unlink(filename)
+
+ bmpfile = open(filename, 'wb')
+
+ fileinfoheader = self.get_fileinfoheader()
+ bmpfile.write(fileinfoheader)
+
+ bmpinfoheader = self.get_bitmapinfoheader()
+ bmpfile.write(bmpinfoheader)
+
+ palette = self.get_palette()
+ bmpfile.write(palette)
+
+ pixeldata = self.get_pixeldata()
+ bmpfile.write(pixeldata)
+
+ bmpfile.close()
+
+ def write_croppped_bitmap(self, filename):
+ """
+ Write the bitmap out to a file, but end the file short in the
+ middle of scaneline.
+ """
+
+ _safe_unlink(filename)
+
+ bmpfile = open(filename, 'wb')
+
+ fileinfoheader = self.get_fileinfoheader()
+ bmpfile.write(fileinfoheader)
+
+ bmpinfoheader = self.get_bitmapinfoheader()
+ bmpfile.write(bmpinfoheader)
+
+ palette = self.get_palette()
+ bmpfile.write(palette)
+
+ # crop the pixel data roughly in half
+ # really, crop it in the middle of a scanline
+ pixeldata = self.get_pixeldata()
+ crop_point = len(pixeldata) // 2 - (self.width * self.bits_per_pixel // 8) // 2 - 1
+ content = pixeldata[0 : crop_point]
+ bmpfile.write(content)
+
+ bmpfile.close()
+
+
+class bitmap_32bpp(bitmap):
+ "A bitmap that is 32 bpp uncompressed RGB."
+
+ def __init__(self, width, height):
+ bitmap.__init__(self, 32, width, height)
+
+ def create_raster(self):
+ "Return the rasterized form of the canonical image in 32 bpp"
+
+ red_width = self.width / 3
+ green_width = self.width / 3
+ blue_width = self.width - (red_width + green_width)
+
+ # draw the color pattern
+ raster = []
+ for i in range(0, self.height):
+
+ row = []
+ row += [struct.pack('<I', 0x00FF0000)] * red_width
+ row += [struct.pack('<I', 0x0000FF00)] * green_width
+ row += [struct.pack('<I', 0x000000FF)] * blue_width
+
+ raster.append(row)
+
+ # draw a border
+ self.draw_double_border(
+ raster,
+ struct.pack('<I', 0x00000000),
+ struct.pack('<I', 0x00FFFFFF))
+
+ # add in the TOP_LEFT_LOGO
+ self.apply_top_left_logo(
+ raster,
+ struct.pack('<I', 0x00000000),
+ struct.pack('<I', 0x00FFFFFF))
+
+ return raster
+
+ def create_pixeldata(self):
+ "Return the pixel data as uncompressed 32 bpp RGB"
+
+ raster = self.create_raster()
+
+ # concatenate the rows in the raster image into a flat buffer
+ pixeldata = ''
+ for row in raster:
+ pixeldata += string.join(row, '')
+
+ return pixeldata
+
+
+class bitmap_32bpp_topdown(bitmap_32bpp):
+ "A 'top down' uncompressed RGB bitmap that has 32 bits per pixel."
+
+ def get_height(self):
+ # a negative value makes a bitmap top-down
+ return -self.height
+
+
+class bitmap_32bpp_colortable(bitmap_32bpp):
+ """
+ A bitmap that is 32 bpp uncompressed RGB.
+ This bitmap has an 'optimal color palette', which is used for optimizing colors on
+ palette-based devices, but does NOT have any color masks.
+ It's unclear to me if this is well-formed or not.
+ """
+
+ def __init__(self, width, height):
+ bitmap_32bpp.__init__(self, width, height)
+
+ self.palette = [
+ 0x00FF00FF, # magenta
+ 0x00000000, # black
+ 0x00FF0000, # red
+ 0x0000FF00, # green
+ 0x000000FF, # blue
+ 0x00FFFFFF] # white
+
+
+class bitmap_32bpp_888_colortable(bitmap_32bpp):
+ """
+ A bitmap that is 32 bpp uncompressed RGB.
+ This bitmap has three DWORD color masks, followed by an 'optimal color palette',
+ which is used for optimizing colors on palette-based devices.
+ """
+
+ def __init__(self, width, height):
+ bitmap_32bpp.__init__(self, width, height)
+
+ self.palette = [
+ 0x00FF0000, # red mask
+ 0x0000FF00, # green mask
+ 0x000000FF, # blue mask
+
+ 0x00FF00FF, # magenta
+ 0x00000000, # black
+ 0x00FF0000, # red
+ 0x0000FF00, # green
+ 0x000000FF, # blue
+ 0x00FFFFFF] # white
+
+ def get_colors_used(self):
+ "Return the biClrUsed to put into the BITMAPINFOHEADER"
+ # This only includes the optimized color palette--not the color masks.
+ return 6
+
+ def get_compression(self):
+ "Return the biCompression to put into the BITMAPINFOHEADER"
+ # must be BI_BITFIELDS because we have color masks
+ return self.BI_BITFIELDS
+
+class bitmap_32bpp_101110(bitmap):
+ """
+ A bitmap that is 32 bpp uncompressed RGB.
+ This bitmap uses 10-11-10 RGB color masks.
+ """
+
+ def __init__(self, width, height):
+ bitmap.__init__(self, 32, width, height)
+
+ self.palette = [
+ 0x7FE00000, # red mask (10 bits)
+ 0x001FFC00, # green mask (11 bits)
+ 0x000003FF] # blue mask (10 bits)
+
+ def get_compression(self):
+ "Return the biCompression to put into the BITMAPINFOHEADER"
+ return self.BI_BITFIELDS
+
+ def get_colors_used(self):
+ "Return the biClrUsed to put into the BITMAPINFOHEADER"
+ return 0
+
+ def create_pixeldata(self):
+ "Return the pixel data as uncompressed 32 bpp RGB"
+
+ red_width = self.width / 3
+ green_width = self.width / 3
+ blue_width = self.width - (red_width + green_width)
+
+ # draw the color pattern
+ raster = []
+ for i in range(0, self.height):
+
+ row = []
+ row += [struct.pack('<I', 0x7FE00000)] * red_width
+ row += [struct.pack('<I', 0x001FFC00)] * green_width
+ row += [struct.pack('<I', 0x000003FF)] * blue_width
+
+ raster.append(row)
+
+ # draw a border
+ self.draw_double_border(
+ raster,
+ struct.pack('<I', 0x00000000),
+ struct.pack('<I', 0x7FFFFFFF))
+
+ # add in the TOP_LEFT_LOGO
+ self.apply_top_left_logo(
+ raster,
+ struct.pack('<I', 0x00000000),
+ struct.pack('<I', 0x7FFFFFFF))
+
+ # concatenate the rows in the raster image into a flat buffer
+ pixeldata = ''
+ for row in raster:
+ pixeldata += string.join(row, '')
+
+ return pixeldata
+
+class bitmap_32bpp_croppedpixeldata(bitmap_32bpp):
+ """
+ A 32 bpp bitmap that ends in the middle of the pixel data.
+ This tests that what happens when a call to fread() fails.
+ This bitmap processor should probably process the data that
+ it does have AND display a diagnostic.
+ """
+
+ def write(self, filename):
+ self.write_croppped_bitmap(filename)
+
+class bitmap_24bpp(bitmap):
+ "An uncompressed bitmap with 24 bits per pixel. "
+
+ def __init__(self, width, height):
+ bitmap.__init__(self, 24, width, height)
+
+ def create_pixeldata(self):
+ "Return the pixel data as uncompressed 24 bpp RGB"
+
+ red_width = self.width / 3
+ green_width = self.width / 3
+ blue_width = self.width - (red_width + green_width)
+
+ pad_width_in_bytes = self.get_scanline_padding_bits() / 8
+
+ # draw the color pattern
+ raster = []
+ for i in range(0, self.height):
+
+ row = []
+ row += ['x00x00xFF'] * red_width
+ row += ['x00xFFx00'] * green_width
+ row += ['xFFx00x00'] * blue_width
+
+ # pad the scanline to the nearest DWORD boundry
+ row += ['xCC'] * pad_width_in_bytes
+
+ raster.append(row)
+
+ # draw a border
+ self.draw_double_border(
+ raster,
+ 'x00x00x00',
+ 'xFFxFFxFF')
+
+ # add in the TOP_LEFT_LOGO
+ self.apply_top_left_logo(
+ raster,
+ 'x00x00x00',
+ 'xFFxFFxFF')
+
+ # concatenate the rows in the raster image into a flat buffer
+ pixeldata = ''
+ for row in raster:
+ pixeldata += string.join(row, '')
+
+ return pixeldata
+
+
+class bitmap_24bpp_topdown(bitmap_24bpp):
+ "A 'top down' bitmap that has 24 bits per pixel."
+
+ def get_height(self):
+ # a negative value makes a bitmap top-down
+ return -self.height
+
+class bitmap_24bpp_zeroimagesize(bitmap_24bpp):
+ """
+ An uncompressed RGB bitmaps that has 24 bits-per-pixel.
+ The bitmap has a biSizeImage field of 0.
+ The bitmap specification allows the biSizeImage field to be zero
+ for uncompressed images.
+ """
+
+ def get_image_size(self):
+ "Return the biSizeImage to put into the BITMAPINFOHEADER"
+ return 0
+
+class bitmap_24bpp_croppedpixeldata(bitmap_24bpp):
+ """
+ A 24 bpp bitmap that ends in the middle of the pixel data.
+ This tests that what happens when a call to fread() fails.
+ This bitmap processor should probably process the data that
+ it does have AND display a diagnostic.
+ """
+
+ def write(self, filename):
+ self.write_croppped_bitmap(filename)
+
+class bitmap_555(bitmap):
+ "A bitmap that is 5-5-5 uncompressed RGB"
+
+ def __init__(self, width, height):
+ bitmap.__init__(self, 16, width, height)
+
+ def create_pixeldata(self):
+ "Return the pixel data as uncompressed 5-5-5 RGB"
+
+ red_width = self.width / 3
+ green_width = self.width / 3
+ blue_width = self.width - (red_width + green_width)
+
+ pad_width_in_bytes = self.get_scanline_padding_bits() / 8
+
+ # draw the color pattern
+ raster = []
+ for i in range(0, self.height):
+
+ row = []
+ row += [struct.pack('<H', 0x7C00)] * red_width
+ row += [struct.pack('<H', 0x03E0)] * green_width
+ row += [struct.pack('<H', 0x001F)] * blue_width
+
+ # pad the scanline to the nearest DWORD boundry
+ row += ['xCC'] * pad_width_in_bytes
+
+ raster.append(row)
+
+ # draw a border
+ self.draw_double_border(
+ raster,
+ 'x00x00',
+ 'xFFxFF')
+
+ # add in the TOP_LEFT_LOGO
+ self.apply_top_left_logo(
+ raster,
+ 'x00x00',
+ 'xFFxFF')
+
+ # concatenate the rows in the raster image into a flat buffer
+ pixeldata = ''
+ for row in raster:
+ pixeldata += string.join(row, '')
+
+ return pixeldata
+
+
+class bitmap_555_croppedpixeldata(bitmap_555):
+ """
+ A 5-5-5 16 bpp bitmap that ends in the middle of the pixel data.
+ This tests that what happens when a call to fread() fails.
+ This bitmap processor should probably process the data that
+ it does have AND display a diagnostic.
+ """
+
+ def write(self, filename):
+ self.write_croppped_bitmap(filename)
+
+class bitmap_565(bitmap):
+ "A bitmap that is 5-6-5 uncompressed RGB"
+
+ def __init__(self, width, height):
+ bitmap.__init__(self, 16, width, height)
+
+ # This is the bitfields (or bitmasks)
+ self.palette = [
+ 0xF800, # 5 bits for red
+ 0x07E0, # 6 bits for green
+ 0x001F] # 5 bits for blue
+
+ def get_compression(self):
+ "Return the biCompression to put into the BITMAPINFOHEADER"
+ return self.BI_BITFIELDS
+
+ def get_colors_used(self):
+ "Return the biClrUsed to put into the BITMAPINFOHEADER"
+ return 0
+
+ def create_pixeldata(self):
+ "Return the pixel data as uncompressed 5-6-5 RGB"
+
+ red_width = self.width / 3
+ green_width = self.width / 3
+ blue_width = self.width - (red_width + green_width)
+
+ pad_width_in_bytes = self.get_scanline_padding_bits() / 8
+
+ # draw the color pattern
+ raster = []
+ for i in range(0, self.height):
+
+ row = []
+ row += [struct.pack('<H', 0xF800)] * red_width
+ row += [struct.pack('<H', 0x07E0)] * green_width
+ row += [struct.pack('<H', 0x001F)] * blue_width
+
+ # pad the scanline to the nearest DWORD boundry
+ row += ['xCC'] * pad_width_in_bytes
+
+ raster.append(row)
+
+ # draw a border
+ self.draw_double_border(
+ raster,
+ 'x00x00',
+ 'xFFxFF')
+
+ # add in the TOP_LEFT_LOGO
+ self.apply_top_left_logo(
+ raster,
+ 'x00x00',
+ 'xFFxFF')
+
+ # concatenate the rows in the raster image into a flat buffer
+ pixeldata = ''
+ for row in raster:
+ pixeldata += string.join(row, '')
+
+ return pixeldata
+
+
+class bitmap_565_topdown(bitmap_565):
+ "A 'top down' bitmap that is 5-6-5 uncompressed RGB."
+
+ def get_height(self):
+ # a negative value makes a bitmap top-down
+ return -self.height
+
+
+
+class bitmap_8bpp(bitmap):
+ "An uncompressed RGB bitmap that has 8 bits per pixel."
+
+ def __init__(self, width, height):
+ bitmap.__init__(self, 8, width, height)
+
+ # Set the "0" pixel to magenta so we can test the
+ # difference between pixels we deliberately set to
+ # black and pixels that the bitmap processor left at 0.
+ self.palette = [
+ 0x00FF00FF, # magenta
+ 0x00000000, # black
+ 0x00FF0000, # red
+ 0x0000FF00, # green
+ 0x000000FF, # blue
+ 0x00FFFFFF] # white
+
+ self.INDEX_MAGENTA = 0
+ self.INDEX_BLACK = 1
+ self.INDEX_RED = 2
+ self.INDEX_GREEN = 3
+ self.INDEX_BLUE = 4
+ self.INDEX_WHITE = 5
+
+ # TRANSPARENT_PIXEL is a special value that means
+ # "use a delta to skip beyond this pixel"
+ self.TRANSPARENT_PIXEL = -2
+
+ def create_pixeldata(self):
+ "Return the pixel data as uncompressed 8 bpp"
+
+ red_width = self.width / 3
+ green_width = self.width / 3
+ blue_width = self.width - (red_width + green_width)
+
+ pad_width_in_bytes = self.get_scanline_padding_bits() / 8
+
+ # draw the color pattern
+ raster = []
+ for i in range(0, self.height):
+
+ row = []
+ row += [chr(self.INDEX_RED)] * red_width
+ row += [chr(self.INDEX_GREEN)] * green_width
+ row += [chr(self.INDEX_BLUE)] * blue_width
+ row += [chr(self.INDEX_MAGENTA)] * pad_width_in_bytes
+
+ raster.append(row)
+
+ # draw a border
+ self.draw_double_border(
+ raster,
+ chr(self.INDEX_BLACK),
+ chr(self.INDEX_WHITE))
+
+ # add in the TOP_LEFT_LOGO
+ self.apply_top_left_logo(
+ raster,
+ chr(self.INDEX_BLACK),
+ chr(self.INDEX_WHITE))
+
+ # concatenate the rows in the raster image into a flat buffer
+ pixeldata = ''
+ for row in raster:
+ pixeldata += string.join(row, '')
+
+ return pixeldata
+
+
+class bitmap_8bpp_topdown(bitmap_8bpp):
+ "A 'top down' uncompressed RGB bitmap that has 8 bits per pixel."
+
+ def get_height(self):
+ # a negative value makes a bitmap top-down
+ return -self.height
+
+
+
+class bitmap_8bpp_pixelnotinpalette(bitmap_8bpp):
+ """
+ A bitmap that is 8 bits per pixel uncompressed RGB.
+ Many of the pixels are indexes that don't exist in the palette.
+ """
+
+ def __init__(self, width, height):
+ bitmap_8bpp.__init__(self, width, height)
+
+ self.palette = [
+ 0x00000000, # black
+ 0x00FFFFFF] # white
+
+ def create_pixeldata(self):
+ "Return the pixel data as uncompressed 8 bpp"
+
+ pad_width_in_bytes = self.get_scanline_padding_bits() / 8
+
+ palette_length = len(self.palette)
+
+ # the raster loops through all 256 possible indices
+ raster = []
+ for row in range(0, self.height):
+
+ new_row = []
+ for col in range(0, self.width + pad_width_in_bytes):
+ # don't draw anything in the palette
+ value = chr((col % (256 - palette_length) + palette_length))
+ new_row.append(value)
+
+ raster.append(new_row)
+
+ # draw a border
+ self.draw_double_border(
+ raster,
+ chr(self.INDEX_BLACK),
+ chr(self.INDEX_WHITE))
+
+ # add in the TOP_LEFT_LOGO
+ self.apply_top_left_logo(
+ raster,
+ chr(self.INDEX_BLACK),
+ chr(self.INDEX_WHITE))
+
+ # concatenate the rows in the raster image into a flat buffer
+ pixeldata = ''
+ for row in raster:
+ pixeldata += string.join(row, '')
+
+ return pixeldata
+
+
+class bitmap_8bpp_nopalette(bitmap_8bpp):
+ """
+ A bitmap that has 8 bits per pixel and no palette.
+ This is an invalid bitmap, but a bitmap processor could use default colors.
+ """
+
+ def __init__(self, width, height):
+ bitmap_8bpp.__init__(self, width, height)
+
+ # empty the palette
+ self.palette = []
+
+class bitmap_8bpp_zerocolorsused(bitmap_8bpp):
+ """
+ An 8 bpp bitmap with a 'biColorsUsed' field of 0.
+ This indicates that the palette contains 256 entries, which it does.
+ """
+
+ def __init__(self, width, height):
+ bitmap_8bpp.__init__(self, width, height)
+
+ # fill the palette
+ while len(self.palette) < 256:
+ self.palette.append(0x00CCCCCC)
+
+ def get_colors_used(self):
+ return 0
+
+class bitmap_8bpp_largecolorsused(bitmap_8bpp):
+ """
+ An 8 bpp bitmap with a very large 'biColorsUsed' field.
+ This is invalid--biColorsImportant shouldn't exceed 256.
+ This attempts to trick the bitmap processor into accessing invalid memory.
+ """
+ def get_colors_used(self):
+ return 0xFFFFFFFF
+
+class bitmap_8bpp_negativecolorsused(bitmap_8bpp):
+ """
+ An 8 bpp bitmap with a negative 'biColorsUsed' field.
+ This is invalid--biColorsImportant can't be below 0.
+ This attempts to trick the bitmap processor into accessing invalid memory.
+ """
+ def get_colors_used(self):
+ # -1024 in 32 bit two complement
+ return 0xFFFFFC00
+
+class bitmap_8bpp_twocolorsimportant(bitmap_8bpp):
+ """
+ An 8 bpp bitmap with five colors, but a 'biColorsImportant' field of 2.
+ This indicates that only black and white are important.
+ """
+ def get_colors_important(self):
+ return 2
+
+class bitmap_8bpp_largecolorsimportant(bitmap_8bpp):
+ """
+ An 8 bpp bitmap with five colors, but a very large 'biColorsImportant' field.
+ This is invalid--biColorsImportant shouldn't exceed biColorsUsed.
+ """
+ def get_colors_important(self):
+ return 0xFFFFFFFF
+
+class bitmap_8bpp_negativecolorsimportant(bitmap_8bpp):
+ """
+ An 8 bpp bitmap with a negative 'biColorsImportant' field.
+ This is invalid--biColorsImportant can't be below 0.
+ """
+ def get_colors_used(self):
+ # -1024 in 32 bit two complement
+ return 0xFFFFFC0
+
+class bitmap_8bpp_croppedpixeldata(bitmap_8bpp):
+ """
+ An 8 bpp bitmap that ends in the middle of the pixel data.
+ This tests that what happens when a call to fread() fails.
+ This bitmap processor should probably process the data that
+ it does have AND display a diagnostic.
+ """
+
+ def write(self, filename):
+ self.write_croppped_bitmap(filename)
+
+class bitmap_rle8(bitmap_8bpp):
+ "A base class for RLE8 bitmaps that implements some helpers routines."
+
+ def get_compression(self):
+ "Return the biCompression to put into the BITMAPINFOHEADER"
+ return self.BI_RLE8
+
+ def create_absolute_run(self, row, offset, length):
+ "Return the 'absolute mode' encoding of a run of pixels"
+
+ if length < 3:
+ raise 'bad length: %d' % length
+
+ if 255 < length:
+ raise 'bad length: %d' % length
+
+ # There are between 3 and 255 pixels left in this row.
+
+ # Mark this run as an absolute encoding
+ encoded_run = 'x00' + chr(length)
+
+ for i in range(0, length):
+ # Encode each pixel with absolute encoding.
+ encoded_run += chr(row[offset + i])
+
+ if len(encoded_run) % 2 != 0:
+ # pad the encoded run out to the nearest word boundry
+ encoded_run += 'x00'
+
+ return encoded_run
+
+ def create_encoded_run(self, run_length, pixel):
+ "Return the 'encoded mode' encoding of a run of pixels"
+ return chr(run_length) + chr(pixel)
+
+ def create_end_of_line(self):
+ "Return the end-of-line escape sequence"
+ return 'x00x00'
+
+ def create_end_of_bitmap(self):
+ "Return the end-of-bitmap escape sequence"
+ return 'x00x01'
+
+ def create_delta(self, right, down):
+ "Return a delta escape sequence"
+ return 'x00x02' + chr(right) + chr(down)
+
+ def create_pixeldata(self):
+ raise "this should not be called"
+
+ def create_raster(self):
+ "Return a rasterized version of the 8bpp canonical image"
+
+ # widths are in bytes (pixels)
+ red_width = self.width / 3
+ green_width = self.width / 3
+ blue_width = self.width - (red_width + green_width)
+
+ # draw the pattern
+ raster = []
+ for i in range(0, self.height):
+
+ row = []
+ row += [self.INDEX_RED] * red_width
+ row += [self.INDEX_GREEN] * green_width
+ row += [self.INDEX_BLUE] * blue_width
+
+ raster.append(row)
+
+ # draw a border
+ self.draw_double_border(
+ raster,
+ self.INDEX_BLACK,
+ self.INDEX_WHITE)
+
+ # add in the TOP_LEFT_LOGO
+ self.apply_top_left_logo(
+ raster,
+ self.INDEX_BLACK,
+ self.INDEX_WHITE)
+
+ return raster
+
+
+class bitmap_rle8_encoded(bitmap_rle8):
+ """
+ A simple run-length encoded bitmap that has 8 bits per pixel.
+ The entire bitmap is in 'encoded mode'.
+ """
+
+ def create_pixeldata(self):
+ "Return the pixel data as run-length encoded 4 bpp"
+
+ raster = self.create_raster()
+
+ pixeldata = ''
+ run_length = 0
+ prev_pixel = -1
+ for row in range(0, len(raster)):
+ for col in range(0, len(raster[row])):
+
+ cur_pixel = raster[row][col]
+
+ if run_length == 255 or (run_length != 0 and prev_pixel != cur_pixel):
+ # There's no more room on this run OR
+ # The current run has ended.
+
+ # Write the run and start a new one
+ pixeldata += self.create_encoded_run(run_length, prev_pixel)
+
+ run_length = 0
+ prev_pixel = -1
+
+
+ if run_length == 0:
+ # start a new run
+ prev_pixel = cur_pixel
+ run_length = 1
+
+ elif prev_pixel == raster[row][col]:
+ # continue this run
+ run_length += 1
+
+ # flush the last run
+ if run_length != 0:
+ pixeldata += self.create_encoded_run(run_length, prev_pixel)
+
+ run_length = 0
+ prev_pixel = -1
+
+ # end-of-line
+ pixeldata += self.create_end_of_line()
+
+ # end-of-bitmap
+ pixeldata += self.create_end_of_bitmap()
+
+ return pixeldata
+
+
+class bitmap_rle8_delta(bitmap_rle8):
+ """
+ A simple run-length encoded bitmap that has 8 bits per pixel.
+ The bitmap uses 'delta escapes'.
+ """
+
+ def __init__(self, width, height):
+ bitmap_rle8.__init__(self, width, height)
+
+ # fill the rest of the palette with grey
+ for i in range(len(self.palette), 256):
+ self.palette.append(0x00CCCCCC)
+
+ def create_raster(self):
+ "Return a rastersized form of a bitmap that is good for making deltas"
+
+ # widths are in bytes (pixels)
+ red_width = self.width / 3
+ green_width = self.width / 3
+ blue_width = self.width - (red_width + green_width)
+
+ # draw the pattern
+ raster = []
+ for i in range(0, self.height):
+
+ row = []
+ row += [self.INDEX_RED] * red_width
+ row += [self.TRANSPARENT_PIXEL] * green_width
+ row += [self.INDEX_BLUE] * blue_width
+
+ raster.append(row)
+
+ # draw an invisible border
+ self.draw_double_border(
+ raster,
+ self.TRANSPARENT_PIXEL,
+ self.TRANSPARENT_PIXEL)
+
+ # add in the TOP_LEFT_LOGO
+ self.apply_top_left_logo(
+ raster,
+ self.INDEX_BLACK,
+ self.INDEX_WHITE)
+
+ return raster
+
+ def create_pixeldata(self):
+ "Return the pixel data as run-length encoded 8 bpp"
+
+ raster = self.create_raster()
+
+ pixeldata = ''
+ run_length = 0
+ prev_pixel = -1
+ for row in range(0, len(raster)):
+
+ # check if the row contains nothing but transparent pixels
+ row_is_all_transparent = 1
+ for col in range(0, len(raster[row])):
+ if raster[row][col] != self.TRANSPARENT_PIXEL:
+ row_is_all_transparent = 0
+ break
+
+ if row_is_all_transparent:
+ # the entire row is entirely transparent. Do a delta.
+ pixeldata += self.create_delta(0, 1)
+
+ else:
+ # there are some non-transparent pixels in this row.
+ for col in range(0, len(raster[row])):
+
+ cur_pixel = raster[row][col]
+
+ if run_length == 255 or (run_length != 0 and prev_pixel != cur_pixel):
+ # There's no more room on this run OR
+ # The current run has ended.
+
+ # Write the run and start a new one
+ if prev_pixel == self.TRANSPARENT_PIXEL:
+ # this run is encoded as a delta
+ pixeldata += self.create_delta(
+ run_length,
+ 0)
+ else:
+ # this run is encoded as a regular run
+ pixeldata += self.create_encoded_run(
+ run_length,
+ prev_pixel)
+
+ run_length = 0
+ prev_pixel = -1
+
+
+ if run_length == 0:
+ # start a new run
+ prev_pixel = cur_pixel
+ run_length = 1
+
+ elif prev_pixel == raster[row][col]:
+ # continue this run
+ run_length += 1
+
+ # flush the last run
+ if run_length != 0:
+
+ # We don't have to write a delta for transparent
+ # pixels because the end-of-line marker will take
+ # care of that.
+ if prev_pixel != self.TRANSPARENT_PIXEL:
+ # this run is encoded as a regular run
+ pixeldata += self.create_encoded_run(
+ run_length,
+ prev_pixel)
+
+ run_length = 0
+ prev_pixel = -1
+
+ # end-of-line
+ pixeldata += self.create_end_of_line()
+
+ # end-of-bitmap
+ pixeldata += self.create_end_of_bitmap()
+
+ return pixeldata
+
+
+class bitmap_rle8_absolute(bitmap_rle8):
+ """
+ A run-length encoded bitmap that has 8 bits per pixel.
+ The entire bitmap is in 'absolute mode'.
+ """
+
+ def create_pixeldata(self):
+ "Return the pixel data as an RLE8 in absolute mode (uncompressed)"
+
+ raster = self.create_raster()
+
+ pixeldata = ''
+ for row in range(0, len(raster)):
+
+ cur_row = raster[row]
+
+ col = 0
+ while col < len(cur_row):
+ remaining = len(cur_row) - col
+ if 255 < remaining:
+ # There are more than 255 pixels left in this row.
+ # Encode all 255 pixels.
+ pixeldata += self.create_absolute_run(cur_row, col, 255)
+ col += 255
+
+ elif 3 <= remaining:
+ # There are between 3 and 255 pixels left in this row.
+ # Encode them all with absolute encoding.
+ pixeldata += self.create_absolute_run(cur_row, col, remaining)
+ col += remaining
+
+ else:
+ raise 'Unsupported width: %d' % remaining
+
+ # end-of-line
+ pixeldata += self.create_end_of_line()
+
+ # end-of-bitmap
+ pixeldata += self.create_end_of_bitmap()
+
+ return pixeldata
+
+
+class bitmap_rle8_blank(bitmap_rle8):
+ """
+ A simple run-length encoded bitmap consists of just an end-of-bitmap marker.
+ """
+
+ def __init__(self, width, height):
+ bitmap_rle8.__init__(self, width, height)
+
+ # fill the rest of the palette with grey
+ # so that we can see the difference between uninitialized
+ # memory and pixels that should be unspecified.
+ for i in range(len(self.palette), 256):
+ self.palette.append(0x00CCCCCC)
+
+ def create_pixeldata(self):
+ "Return the pixel data as run-length encoded 8 bpp"
+
+ return self.create_end_of_bitmap()
+
+
+class bitmap_rle8_noendofbitmap(bitmap_rle8_encoded):
+ """
+ An RLE8 compressed bitmap with no end-of-bitmap sequence.
+ This is techinically invalid, but the bitmap processor should
+ be able to treat the end-of-file as an end-of-bitmap.
+ """
+
+ def create_end_of_bitmap(self):
+ return ''
+
+
+class bitmap_rle8_topdown(bitmap_rle8_encoded):
+ """
+ An RLE8 compressed bitmap with a negative height.
+ This is an illegal value: top-down images cannot be compressed.
+ However, many bitmap processors allow top-down compressed images.
+ """
+
+ def get_height(self):
+ return -self.height
+
+
+class bitmap_rle8_toomuchdata(bitmap_rle8_encoded):
+ """
+ A simple run-length encoded bitmap that has 8 bits per pixel.
+ The entire bitmap is in 'encoded mode'.
+ It has twice as much data as it should.
+ Since the RLE8 format is mostly a series of drawing directives,
+ this tests that the RLE8 processor keeps memory access within
+ the size of the image.
+ """
+
+ def create_pixeldata(self):
+ "Return the pixel data as run-length encoded in 8 bpp"
+
+ raster = self.create_raster()
+
+ pixeldata = ''
+ run_length = 0
+ prev_pixel = -1
+ for row in range(0, len(raster)):
+ for col in range(0, len(raster[row])):
+
+ cur_pixel = raster[row][col]
+
+ if run_length == 255 or (run_length != 0 and prev_pixel != cur_pixel):
+ # There's no more room on this run OR
+ # The current run has ended.
+
+ # Write the run and start a new one
+ pixeldata += self.create_encoded_run(run_length, prev_pixel)
+
+ run_length = 0
+ prev_pixel = -1
+
+
+ if run_length == 0:
+ # start a new run
+ prev_pixel = cur_pixel
+ run_length = 1
+
+ elif prev_pixel == raster[row][col]:
+ # continue this run
+ run_length += 1
+
+ # flush the last run
+ if run_length != 0:
+ pixeldata += self.create_encoded_run(run_length, prev_pixel)
+
+ run_length = 0
+ prev_pixel = -1
+
+ # end-of-line
+ pixeldata += self.create_end_of_line()
+
+ # double the height of the image.
+ pixeldata *= 2
+
+ # end-of-bitmap
+ pixeldata += self.create_end_of_bitmap()
+
+ return pixeldata
+
+
+class bitmap_rle8_deltaleavesimage(bitmap_rle8_encoded):
+ """
+ A simple run-length encoded bitmap that has 8 bits per pixel.
+ The bitmap contains 'delta' escape sequences the leave the image.
+ The intent is to trick the processor into accessing invalid memory.
+ """
+
+ def create_pixeldata(self):
+ "Return the pixel data as run-length encoded 8 bpp"
+
+ # Tell the image processor to move off of the image
+ # before drawing anything.
+ pixeldata = ''
+ i = 0
+ while i < self.height:
+ pixeldata += self.create_delta(255, 0)
+ i += 255
+
+ # draw the image
+ pixeldata += bitmap_rle8_encoded.create_pixeldata(self)
+
+ return pixeldata
+
+
+class bitmap_rle8_croppedrun(bitmap_rle8):
+ """
+ A simple run-length encoded bitmap that has 8 bits per pixel.
+ The entire bitmap is in 'encoded mode'.
+ The pixel data ends prematurely--in the middle of an encoded
+ escape sequence.
+ """
+
+ def create_pixeldata(self):
+ "Return the pixel data as run-length encoded 8 bpp"
+
+ raster = self.create_raster()
+
+ pixeldata = ''
+ run_length = 0
+ prev_pixel = -1
+ for row in range(0, len(raster) / 2):
+ for col in range(0, len(raster[row])):
+
+ cur_pixel = raster[row][col]
+
+ if run_length == 255 or (run_length != 0 and prev_pixel != cur_pixel):
+ # There's no more room on this run OR
+ # The current run has ended.
+
+ # Write the run and start a new one
+ pixeldata += self.create_encoded_run(run_length, prev_pixel)
+
+ run_length = 0
+ prev_pixel = -1
+
+
+ if run_length == 0:
+ # start a new run
+ prev_pixel = cur_pixel
+ run_length = 1
+
+ elif prev_pixel == raster[row][col]:
+ # continue this run
+ run_length += 1
+
+ # flush the last run
+ if run_length != 0:
+ pixeldata += self.create_encoded_run(run_length, prev_pixel)
+
+ run_length = 0
+ prev_pixel = -1
+
+ # end-of-line
+ pixeldata += self.create_end_of_line()
+
+ # append the cropped run
+ last_run = self.create_encoded_run(100, 2)
+ cropped_run = last_run[0 : len(last_run) - 1]
+ pixeldata += cropped_run
+
+ return pixeldata
+
+
+class bitmap_rle8_croppedabsolute(bitmap_rle8):
+ """
+ A simple run-length encoded bitmap that has 8 bits per pixel.
+ The entire bitmap is in 'absolute mode'.
+ The pixel data ends prematurely--in the middle of an absolute
+ escape sequence.
+ """
+
+ def create_pixeldata(self):
+ "Return the pixel data as RLE8 encoded in 'absolute mode' (uncompressed)"
+ raster = self.create_raster()
+
+ pixeldata = ''
+ for row in range(0, len(raster)):
+
+ cur_row = raster[row]
+
+ col = 0
+ while col < len(cur_row):
+ remaining = len(cur_row) - col
+ if 255 < remaining:
+ # There are more than 255 pixels left in this row.
+ # Encode all 255 pixels.
+ absolute_run = self.create_absolute_run(cur_row, col, 255)
+ col += 255
+
+ elif 3 <= remaining:
+ # There are between 3 and 255 pixels left in this row.
+ # Encode them all with absolute encoding.
+ absolute_run = self.create_absolute_run(cur_row, col, remaining)
+ col += remaining
+
+ else:
+ raise 'Unsupported width: %d' % remaining
+
+ if len(raster) / 2 <= row:
+ # crop this encoding and return
+ cropped_run = absolute_run[0 : len(absolute_run) - 1]
+ pixeldata += cropped_run
+ return pixeldata
+
+ # append this encoding and keep processing the current row
+ pixeldata += absolute_run
+
+ # end-of-line
+ pixeldata += self.create_end_of_line()
+
+ return pixeldata
+
+class bitmap_rle8_croppeddelta(bitmap_rle8_delta):
+ """
+ A simple run-length encoded bitmap that has 8 bits per pixel.
+ The bitmap uses 'delta escapes'.
+ The file ends in the middle of a delta escape.
+ """
+
+ def create_pixeldata(self):
+ "Return the pixel data as run-length encoded 8 bpp"
+
+ raster = self.create_raster()
+
+ pixeldata = ''
+ run_length = 0
+ prev_pixel = -1
+ for row in range(0, len(raster)):
+
+ # check if the row contains nothing but transparent pixels
+ row_is_all_transparent = 1
+ for col in range(0, len(raster[row])):
+ if raster[row][col] != self.TRANSPARENT_PIXEL:
+ row_is_all_transparent = 0
+ break
+
+ if row_is_all_transparent:
+ # the entire row is entirely transparent. Do a delta.
+ pixeldata += self.create_delta(0, 1)
+
+ else:
+ # there are some non-transparent pixels in this row.
+ for col in range(0, len(raster[row])):
+
+ cur_pixel = raster[row][col]
+
+ if run_length == 255 or (run_length != 0 and prev_pixel != cur_pixel):
+ # There's no more room on this run OR
+ # The current run has ended.
+
+ # Write the run and start a new one
+ if prev_pixel == self.TRANSPARENT_PIXEL:
+ # this run is encoded as a delta
+ delta = self.create_delta(
+ run_length,
+ 0)
+
+ if len(raster) / 2 <= row:
+ # we are half-way through the image.
+ # crop the delta and return what we have
+ cropped_delta = delta[0 : len(delta) - 1]
+ pixeldata += cropped_delta
+ return pixeldata
+
+ pixeldata += delta
+
+ else:
+ # this run is encoded as a regular run
+ pixeldata += self.create_encoded_run(
+ run_length,
+ prev_pixel)
+
+ run_length = 0
+ prev_pixel = -1
+
+
+ if run_length == 0:
+ # start a new run
+ prev_pixel = cur_pixel
+ run_length = 1
+
+ elif prev_pixel == raster[row][col]:
+ # continue this run
+ run_length += 1
+
+ # flush the last run
+ if run_length != 0:
+
+ # We don't have to write a delta for transparent
+ # pixels because the end-of-line marker will take
+ # care of that.
+ if prev_pixel != self.TRANSPARENT_PIXEL:
+ # this run is encoded as a regular run
+ pixeldata += self.create_encoded_run(
+ run_length,
+ prev_pixel)
+
+ run_length = 0
+ prev_pixel = -1
+
+ # end-of-line
+ pixeldata += self.create_end_of_line()
+
+ # end-of-bitmap
+ pixeldata += self.create_end_of_bitmap()
+
+ return pixeldata
+
+
+class bitmap_rle8_noendofline(bitmap_rle8_encoded):
+ """
+ An RLE8 compressed bitmap with no end-of-line sequences.
+ It is unclear if a bitmap processor should implicitly add
+ end-of-line markers when the pixel run the row's width,
+ or if it should ignore all pixel data beyond the row's width.
+ """
+
+ def create_end_of_line(self):
+ return ''
+
+
+class bitmap_4bpp(bitmap):
+ "An uncompressed bitmap that has 4 bits per pixel."
+
+ def __init__(self, width, height):
+ bitmap.__init__(self, 4, width, height)
+
+ # Set the "0" pixel to magenta so we can test the
+ # difference between pixels we deliberately set to
+ # black and pixels that the bitmap processor left at 0.
+ self.palette = [
+ 0x00FF00FF, # magenta
+ 0x00000000, # black
+ 0x00FF0000, # red
+ 0x0000FF00, # green
+ 0x000000FF, # blue
+ 0x00FFFFFF] # white
+
+ self.INDEX_MAGENTA = 0
+ self.INDEX_BLACK = 1
+ self.INDEX_RED = 2
+ self.INDEX_GREEN = 3
+ self.INDEX_BLUE = 4
+ self.INDEX_WHITE = 5
+
+ # TRANSPARENT_PIXEL is a special value that means
+ # "use a delta to skip beyond this pixel"
+ self.TRANSPARENT_PIXEL = -2
+
+ def create_pixeldata(self):
+ "Return the pixel data as uncompressed 4 bpp"
+
+ # widths are in nibbles (pixels)
+ red_width = self.width // 3
+ green_width = self.width // 3
+ blue_width = self.width - (red_width + green_width)
+
+ pad_width = self.get_scanline_padding_bits() // 4
+
+ # draw the pattern
+ raster = []
+ for i in range(0, self.height):
+
+ row = []
+ row += [self.INDEX_RED] * red_width
+ row += [self.INDEX_GREEN] * green_width
+ row += [self.INDEX_BLUE] * blue_width
+ row += [self.INDEX_MAGENTA] * pad_width
+
+ raster.append(row)
+
+ # draw a border
+ self.draw_double_border(raster, self.INDEX_BLACK, self.INDEX_WHITE)
+
+ # add in the TOP_LEFT_LOGO
+ self.apply_top_left_logo(raster, self.INDEX_BLACK, self.INDEX_WHITE)
+
+ pixeldata = ''
+ for row in range(0, len(raster)):
+
+ # a closure for helping to add runs to the image
+ class nibblestream:
+ def __init__(self):
+ self.nextByte = 0
+ self.index = 0
+ self.scanline = ''
+
+ def appendnibble(self, value):
+ # shift the byte over and OR-in the low bit
+ self.nextByte = (self.nextByte << 4) | value
+ self.index += 4
+
+ if (self.index == 8):
+ # this byte is full--write it
+ self.scanline += chr(self.nextByte)
+ self.nextByte = 0
+ self.index = 0
+
+ appender = nibblestream()
+ for col in range(0, len(raster[row])):
+ appender.appendnibble(raster[row][col])
+ pixeldata += appender.scanline
+
+ return pixeldata
+
+
+class bitmap_4bpp_topdown(bitmap_4bpp):
+ "A 'top down' uncompressed RGB bitmap that has 4 bits per pixel."
+
+ def get_height(self):
+ # a negative value makes a bitmap top-down
+ return -self.height
+
+class bitmap_4bpp_croppedpixeldata(bitmap_4bpp):
+ """
+ An 4 bpp bitmap that ends in the middle of the pixel data.
+ This tests that what happens when a call to fread() fails.
+ This bitmap processor should probably process the data that
+ it does have AND display a diagnostic.
+ """
+
+ def write(self, filename):
+ self.write_croppped_bitmap(filename)
+
+
+class bitmap_rle4(bitmap_4bpp):
+ "A base class for RLE4 bitmaps that implements some helpers routines."
+
+ def get_compression(self):
+ "Return the biCompression to put into the BITMAPINFOHEADER"
+ return self.BI_RLE4
+
+ def create_absolute_run(self, row, offset, length):
+ "Return the 'absolute mode' encoding of a run of pixels"
+
+ if length < 3:
+ raise 'bad length: %d' % length
+
+ if 255 < length:
+ raise 'bad length: %d' % length
+
+ # There are between 3 and 255 pixels left in this row.
+
+ # Mark this run as an absolute encoding
+ encoded_run = 'x00' + chr(length)
+
+ for i in range(0, length / 2):
+ # Encode each pixel with absolute encoding.
+ byte = (row[offset + 2 * i] << 4) | (row[offset + 2 * i + 1])
+ encoded_run += chr(byte)
+
+ if length % 2 != 0:
+ # We have one pixel left, which fills half a byte.
+ byte = row[offset + length - 1] << 4
+ encoded_run += chr(byte)
+
+ if len(encoded_run) % 2 != 0:
+ # pad the encoded run out to the nearest word boundry
+ encoded_run += 'x00'
+
+ return encoded_run
+
+ def create_encoded_run(self, run_length, pixel1, pixel2):
+ "Return the 'encoded mode' encoding of a run of pixels"
+ return chr(run_length) + chr((pixel1 << 4) | pixel2)
+
+ def create_end_of_line(self):
+ "Return the end-of-line escape sequence"
+ return 'x00x00'
+
+ def create_end_of_bitmap(self):
+ "Return the end-of-bitmap escape sequence"
+ return 'x00x01'
+
+ def create_delta(self, down, right):
+ "Return a delta escape sequence"
+ return 'x00x02' + chr(down) + chr(right)
+
+ def create_pixeldata(self):
+ raise "this should not be called"
+
+ def create_raster(self):
+ "Return a rasterized version of the 4bpp canonical image"
+
+ # widths are in nibbles (pixels)
+ red_width = self.width / 3
+ green_width = self.width / 3
+ blue_width = self.width - (red_width + green_width)
+
+ # draw the pattern
+ raster = []
+ for i in range(0, self.height):
+
+ row = []
+ row += [self.INDEX_RED] * red_width
+ row += [self.INDEX_GREEN] * green_width
+ row += [self.INDEX_BLUE] * blue_width
+
+ raster.append(row)
+
+ # draw a border
+ self.draw_double_border(raster, self.INDEX_BLACK, self.INDEX_WHITE)
+
+ # add in the TOP_LEFT_LOGO
+ self.apply_top_left_logo(raster, self.INDEX_BLACK, self.INDEX_WHITE)
+
+ return raster
+
+
+class bitmap_rle4_encoded(bitmap_rle4):
+ """
+ A simple run-length encoded bitmap that has 4 bits per pixel.
+ The entire bitmap is in 'encoded mode'.
+ """
+
+ def create_pixeldata(self):
+ "Return the pixel data as run-length encoded 4 bpp"
+
+ raster = self.create_raster()
+
+ pixeldata = ''
+ run_length = 0
+ prev_pixel = -1
+ for row in range(0, len(raster)):
+ for col in range(0, len(raster[row])):
+
+ cur_pixel = raster[row][col]
+
+ if run_length == 255 or (run_length != 0 and prev_pixel != cur_pixel):
+ # There's no more room on this run OR
+ # The current run has ended.
+
+ # Write the run and start a new one
+ pixeldata += self.create_encoded_run(run_length, prev_pixel, prev_pixel)
+
+ run_length = 0
+ prev_pixel = -1
+
+
+ if run_length == 0:
+ # start a new run
+ prev_pixel = cur_pixel
+ run_length = 1
+
+ elif prev_pixel == raster[row][col]:
+ # continue this run
+ run_length += 1
+
+ # flush the last run
+ if run_length != 0:
+ pixeldata += self.create_encoded_run(run_length, prev_pixel, prev_pixel)
+
+ run_length = 0
+ prev_pixel = -1
+
+ # end-of-line
+ pixeldata += self.create_end_of_line()
+
+ # end-of-bitmap
+ pixeldata += self.create_end_of_bitmap()
+
+ return pixeldata
+
+
+class bitmap_rle4_absolute(bitmap_rle4):
+ """
+ A run-length encoded bitmap that has 4 bits per pixel.
+ The entire bitmap is in 'absolute mode'.
+ """
+
+ def create_pixeldata(self):
+ "Return the pixel data as RLE4 encoded in 'absolute mode' (uncompressed)"
+
+ raster = self.create_raster()
+
+ pixeldata = ''
+ for row in range(0, len(raster)):
+
+ cur_row = raster[row]
+
+ col = 0
+ while col < len(cur_row):
+ remaining = len(cur_row) - col
+ if 255 < remaining:
+ # There are more than 255 pixels left in this row.
+ # Encode all 255 pixels.
+ pixeldata += self.create_absolute_run(cur_row, col, 255)
+ col += 255
+
+ elif 3 <= remaining:
+ # There are between 3 and 255 pixels left in this row.
+ # Encode them all with absolute encoding.
+ pixeldata += self.create_absolute_run(cur_row, col, remaining)
+ col += remaining
+
+ else:
+ raise 'Unsupported width: %d' % remaining
+
+ # end-of-line
+ pixeldata += self.create_end_of_line()
+
+ # end-of-bitmap
+ pixeldata += self.create_end_of_bitmap()
+
+ return pixeldata
+
+
+
+class bitmap_rle4_alternate(bitmap_rle4):
+ """
+ A simple run-length encoded bitmap that has 4 bits per pixel.
+ The entire bitmap is in 'encoded mode'.
+ The runs encode alternating pixel colors, such as dithering would create.
+ """
+
+ def __init__(self, width, height):
+ bitmap_rle4.__init__(self, width, height)
+
+ self.palette = [
+ 0x00000000, # black
+ 0x00000000, # black
+ 0x00FF0000, # red
+ 0x0000FF00, # green
+ 0x000000FF, # blue
+ 0x00FF0000, # red
+ 0x00FFFFFF, # white
+ 0x00FFFFFF] # white
+
+ def create_pixeldata(self):
+ "Return the pixel data as run-length encoded 4 bpp"
+
+ # widths are in nibbles (pixels)
+ red_width = self.width / 3
+ green_width = self.width / 3
+ blue_width = self.width - (red_width + green_width)
+
+ # draw the pattern
+ raster = []
+ for i in range(0, self.height):
+
+ row = []
+ row += [2] * red_width
+ row += [3] * green_width
+ row += [4] * blue_width
+
+ raster.append(row)
+
+ # draw a border
+ self.draw_double_border(raster, 0, 6)
+
+ # add in the TOP_LEFT_LOGO
+ self.apply_top_left_logo(raster, 0, 6)
+
+ pixeldata = ''
+ run_length = 0
+ prev_pixel = -1
+ for row in range(0, len(raster)):
+ for col in range(0, len(raster[row])):
+
+ cur_pixel = raster[row][col]
+
+ if run_length == 255 or (run_length != 0 and prev_pixel != cur_pixel):
+ # There's no more room on this run OR
+ # The current run has ended.
+
+ # Write the run and start a new one
+ pixeldata += self.create_encoded_run(
+ run_length,
+ prev_pixel,
+ prev_pixel + 1)
+
+ run_length = 0
+ prev_pixel = -1
+
+
+ if run_length == 0:
+ # start a new run
+ prev_pixel = cur_pixel
+ run_length = 1
+
+ elif prev_pixel == raster[row][col]:
+ # continue this run
+ run_length += 1
+
+ # flush the last run
+ if run_length != 0:
+ pixeldata += self.create_encoded_run(
+ run_length,
+ prev_pixel,
+ prev_pixel + 1)
+
+ run_length = 0
+ prev_pixel = -1
+
+ # end-of-line
+ pixeldata += self.create_end_of_line()
+
+ # end-of-bitmap
+ pixeldata += self.create_end_of_bitmap()
+
+ return pixeldata
+
+
+class bitmap_rle4_delta(bitmap_rle4):
+ """
+ A simple run-length encoded bitmap that has 4 bits per pixel.
+ The bitmap uses 'delta escapes'.
+ """
+
+ def __init__(self, width, height):
+ bitmap_rle4.__init__(self, width, height)
+
+ # fill the rest of the palette with grey
+ # so that we can see the difference between uninitialized
+ # memory and pixels that should be unspecified.
+ for i in range(len(self.palette), 16):
+ self.palette.append(0x00CCCCCC)
+
+ def create_raster(self):
+ "Return a raster that is suitable for creating an RLE image with deltas"
+
+ # widths are in bytes (pixels)
+ red_width = self.width / 3
+ green_width = self.width / 3
+ blue_width = self.width - (red_width + green_width)
+
+ # draw the pattern
+ raster = []
+ for i in range(0, self.height):
+
+ row = []
+ row += [self.INDEX_RED] * red_width
+ row += [self.TRANSPARENT_PIXEL] * green_width
+ row += [self.INDEX_BLUE] * blue_width
+
+ raster.append(row)
+
+ # draw an invisible border
+ self.draw_double_border(
+ raster,
+ self.TRANSPARENT_PIXEL,
+ self.TRANSPARENT_PIXEL)
+
+ # add in the TOP_LEFT_LOGO
+ self.apply_top_left_logo(
+ raster,
+ self.INDEX_BLACK,
+ self.INDEX_WHITE)
+
+ return raster
+
+
+ def create_pixeldata(self):
+ "Return the pixel data as run-length encoded 8 bpp"
+
+ raster = self.create_raster()
+
+ pixeldata = ''
+ run_length = 0
+ prev_pixel = -1
+ for row in range(0, len(raster)):
+
+ # check if the row contains nothing but transparent pixels
+ row_is_all_transparent = 1
+ for col in range(0, len(raster[row])):
+ if raster[row][col] != self.TRANSPARENT_PIXEL:
+ row_is_all_transparent = 0
+ break
+
+ if row_is_all_transparent:
+ # the entire row is entirely transparent. Do a delta.
+ pixeldata += self.create_delta(0, 1)
+
+ else:
+ # there are some non-transparent pixels in this row.
+ for col in range(0, len(raster[row])):
+
+ cur_pixel = raster[row][col]
+
+ if run_length == 255 or (run_length != 0 and prev_pixel != cur_pixel):
+ # There's no more room on this run OR
+ # The current run has ended.
+
+ # Write the run and start a new one
+ if prev_pixel == self.TRANSPARENT_PIXEL:
+ # this run is encoded as a delta
+ pixeldata += self.create_delta(
+ run_length,
+ 0)
+ else:
+ # this run is encoded as a regular run
+ pixeldata += self.create_encoded_run(
+ run_length,
+ prev_pixel,
+ prev_pixel)
+
+ run_length = 0
+ prev_pixel = -1
+
+
+ if run_length == 0:
+ # start a new run
+ prev_pixel = cur_pixel
+ run_length = 1
+
+ elif prev_pixel == raster[row][col]:
+ # continue this run
+ run_length += 1
+
+ # flush the last run
+ if run_length != 0:
+
+ # We don't have to write a delta for transparent
+ # pixels because the end-of-line marker will take
+ # care of that.
+ if prev_pixel != self.TRANSPARENT_PIXEL:
+ # this run is encoded as a regular run
+ pixeldata += self.create_encoded_run(
+ run_length,
+ prev_pixel,
+ prev_pixel)
+
+ run_length = 0
+ prev_pixel = -1
+
+ # end-of-line
+ pixeldata += self.create_end_of_line()
+
+ # end-of-bitmap
+ pixeldata += self.create_end_of_bitmap()
+
+ return pixeldata
+
+class bitmap_rle4_topdown(bitmap_rle4_encoded):
+ """
+ An RLE4 compressed bitmap with a negative height.
+ This is an illegal bitmap: top-down images cannot be compressed.
+ Still, many bitmap processors can understand it.
+ """
+
+ def get_height(self):
+ return -self.height
+
+
+class bitmap_rle4_noendofline(bitmap_rle4_encoded):
+ """
+ An RLE4 compressed bitmap with no end-of-line sequences.
+ It is unclear if a bitmap processor should implicitly add
+ end-of-line markers when the pixel run the row's width,
+ or if it should ignore all pixel data beyond the row's width.
+ """
+
+ def create_end_of_line(self):
+ return ''
+
+class bitmap_rle4_noendofbitmap(bitmap_rle4_encoded):
+ """
+ An RLE4 compressed bitmap with no end-of-bitmap sequence.
+ This is techinically invalid, but the bitmap processor should
+ be able to treat the end-of-file as an end-of-bitmap.
+ """
+
+ def create_end_of_bitmap(self):
+ return ''
+
+
+class bitmap_rle4_croppedrun(bitmap_rle4):
+ """
+ A simple run-length encoded bitmap that has 4 bits per pixel.
+ The entire bitmap is in 'encoded mode'.
+ The pixel data ends prematurely--in the middle of an encoded
+ escape sequence.
+ """
+
+ def create_pixeldata(self):
+ "Return the pixel data as run-length encoded 4 bpp"
+
+ raster = self.create_raster()
+
+ pixeldata = ''
+ run_length = 0
+ prev_pixel = -1
+ for row in range(0, len(raster) / 2):
+ for col in range(0, len(raster[row])):
+
+ cur_pixel = raster[row][col]
+
+ if run_length == 255 or (run_length != 0 and prev_pixel != cur_pixel):
+ # There's no more room on this run OR
+ # The current run has ended.
+
+ # Write the run and start a new one
+ pixeldata += self.create_encoded_run(run_length, prev_pixel, prev_pixel)
+
+ run_length = 0
+ prev_pixel = -1
+
+
+ if run_length == 0:
+ # start a new run
+ prev_pixel = cur_pixel
+ run_length = 1
+
+ elif prev_pixel == raster[row][col]:
+ # continue this run
+ run_length += 1
+
+ # flush the last run
+ if run_length != 0:
+ pixeldata += self.create_encoded_run(run_length, prev_pixel, prev_pixel)
+
+ run_length = 0
+ prev_pixel = -1
+
+ # end-of-line
+ pixeldata += self.create_end_of_line()
+
+ # append the cropped run
+ last_run = self.create_encoded_run(100, 1, 2)
+ cropped_run = last_run[0 : len(last_run) - 1]
+ pixeldata += cropped_run
+
+ return pixeldata
+
+class bitmap_rle4_croppedabsolute(bitmap_rle4):
+ """
+ A simple run-length encoded bitmap that has 4 bits per pixel.
+ The entire bitmap is in 'absolute mode'.
+ The pixel data ends prematurely--in the middle of an absolute
+ escape sequence.
+ """
+
+ def create_pixeldata(self):
+ "Return the pixel data as RLE4 encoded in 'absolute mode' (uncompressed)"
+ raster = self.create_raster()
+
+ pixeldata = ''
+ for row in range(0, len(raster)):
+
+ cur_row = raster[row]
+
+ col = 0
+ while col < len(cur_row):
+ remaining = len(cur_row) - col
+ if 255 < remaining:
+ # There are more than 255 pixels left in this row.
+ # Encode all 255 pixels.
+ absolute_run = self.create_absolute_run(cur_row, col, 255)
+ col += 255
+
+ elif 3 <= remaining:
+ # There are between 3 and 255 pixels left in this row.
+ # Encode them all with absolute encoding.
+ absolute_run = self.create_absolute_run(cur_row, col, remaining)
+ col += remaining
+
+ else:
+ raise 'Unsupported width: %d' % remaining
+
+ if len(raster) / 2 <= row:
+ # crop this encoding and return
+ cropped_run = absolute_run[0 : len(absolute_run) - 1]
+ pixeldata += cropped_run
+ return pixeldata
+
+ # append this encoding and keep processing the current row
+ pixeldata += absolute_run
+
+ # end-of-line
+ pixeldata += self.create_end_of_line()
+
+ return pixeldata
+
+class bitmap_rle4_croppeddelta(bitmap_rle4_delta):
+ """
+ A simple run-length encoded bitmap that has 4 bits per pixel.
+ The bitmap uses 'delta escapes'.
+ The file ends in the middle of a delta escape.
+ """
+
+ def create_pixeldata(self):
+ """
+ Return the pixel data as run-length encoded 4 bpp that ends in the
+ middle of a delta escape sequence
+ """
+
+ raster = self.create_raster()
+
+ pixeldata = ''
+ run_length = 0
+ prev_pixel = -1
+ for row in range(0, len(raster)):
+
+ # check if the row contains nothing but transparent pixels
+ row_is_all_transparent = 1
+ for col in range(0, len(raster[row])):
+ if raster[row][col] != self.TRANSPARENT_PIXEL:
+ row_is_all_transparent = 0
+ break
+
+ if row_is_all_transparent:
+ # the entire row is entirely transparent. Do a delta.
+ pixeldata += self.create_delta(0, 1)
+
+ else:
+ # there are some non-transparent pixels in this row.
+ for col in range(0, len(raster[row])):
+
+ cur_pixel = raster[row][col]
+
+ if run_length == 255 or (run_length != 0 and prev_pixel != cur_pixel):
+ # There's no more room on this run OR
+ # The current run has ended.
+
+ # Write the run and start a new one
+ if prev_pixel == self.TRANSPARENT_PIXEL:
+ # this run is encoded as a delta
+ delta = self.create_delta(
+ run_length,
+ 0)
+
+ if len(raster) / 2 <= row:
+ # we are half-way through the image.
+ # crop the delta and return what we have
+ cropped_delta = delta[0 : len(delta) - 1]
+ pixeldata += cropped_delta
+ return pixeldata
+
+ pixeldata += delta
+
+ else:
+ # this run is encoded as a regular run
+ pixeldata += self.create_encoded_run(
+ run_length,
+ prev_pixel,
+ prev_pixel)
+
+ run_length = 0
+ prev_pixel = -1
+
+
+ if run_length == 0:
+ # start a new run
+ prev_pixel = cur_pixel
+ run_length = 1
+
+ elif prev_pixel == raster[row][col]:
+ # continue this run
+ run_length += 1
+
+ # flush the last run
+ if run_length != 0:
+
+ # We don't have to write a delta for transparent
+ # pixels because the end-of-line marker will take
+ # care of that.
+ if prev_pixel != self.TRANSPARENT_PIXEL:
+ # this run is encoded as a regular run
+ pixeldata += self.create_encoded_run(
+ run_length,
+ prev_pixel,
+ prev_pixel)
+
+ run_length = 0
+ prev_pixel = -1
+
+ # end-of-line
+ pixeldata += self.create_end_of_line()
+
+ # end-of-bitmap
+ pixeldata += self.create_end_of_bitmap()
+
+ return pixeldata
+
+
+class bitmap_4bpp_nopalette(bitmap_4bpp):
+ """
+ A bitmap that has 4 bit per pixel and no palette.
+ This is an invalid bitmap, but a bitmap processor could use default colors.
+ """
+
+ def __init__(self, width, height):
+ bitmap_4bpp.__init__(self, width, height)
+
+ # empty the palette
+ self.palette = []
+
+
+class bitmap_1bpp(bitmap):
+ "A bitmap that has 1 bit per pixel."
+
+ def __init__(self, width, height):
+ bitmap.__init__(self, 1, width, height)
+
+ self.palette = [
+ 0x00000000, # black
+ 0x00FFFFFF] # white
+
+ def create_pixeldata(self):
+ "Return the pixel data as uncompressed 1 bpp."
+
+ # widths are in bits (pixels)
+ stripe1_width = self.width // 3
+ stripe2_width = self.width // 3
+ stripe3_width = self.width - (stripe1_width + stripe2_width)
+
+ pad_width_in_bits = self.get_scanline_padding_bits()
+
+ # draw the pattern
+ raster = []
+ for i in range(0, self.height):
+
+ row = []
+ row += [0] * stripe1_width
+ row += [1] * stripe2_width
+ row += [0] * stripe3_width
+ row += [1] * pad_width_in_bits
+
+ raster.append(row)
+
+ # draw a border
+ self.draw_double_border(raster, 0, 1)
+
+ # add in the TOP_LEFT_LOGO
+ self.apply_top_left_logo(raster, 0, 1)
+
+
+ pixeldata = b''
+ for row in range(0, len(raster)):
+
+ # a closure for helping to add runs to the image
+ class bitstream:
+ def __init__(self):
+ self.nextByte = 0
+ self.index = 0
+ self.scanline = b''
+
+ def appendbit(self, value):
+ # shift the byte over and OR-in the low bit
+ self.nextByte = (self.nextByte << 1) | value
+ self.index += 1
+
+ if (self.index == 8):
+ # this byte is full--write it
+ self.scanline += chr(self.nextByte)
+ self.nextByte = 0
+ self.index = 0
+
+ appender = bitstream()
+ for col in range(0, len(raster[row])):
+ appender.appendbit(raster[row][col])
+ pixeldata += appender.scanline
+
+ return pixeldata
+
+class bitmap_1bpp_topdown(bitmap_1bpp):
+ "A 'top down' uncompressed RGB bitmap that has 1 bit per pixel."
+
+ def get_height(self):
+ # a negative value makes a bitmap top-down
+ return -self.height
+
+
+class bitmap_1bpp_color(bitmap_1bpp):
+ "A bitmap that has 1 bit per pixel and a color palette."
+
+ def __init__(self, width, height):
+ bitmap_1bpp.__init__(self, width, height)
+
+ self.palette = [
+ 0x00FFF000, # yellow
+ 0x00000FFF] # mostly blue
+
+class bitmap_1bpp_overlappingcolor(bitmap_1bpp):
+ "A bitmap that has 1 bit per pixel and a color palette with colors that overlap."
+
+ def __init__(self, width, height):
+ bitmap_1bpp.__init__(self, width, height)
+
+ self.palette = [
+ 0x00FFFF00, # yellow
+ 0x0000FFFF] # cyan
+
+class bitmap_1bpp_nopalette(bitmap_1bpp):
+ """
+ A bitmap that has 1 bit per pixel and no palette.
+ This is technically invalid, but a bitmap processor could default to black and white.
+ """
+
+ def __init__(self, width, height):
+ bitmap_1bpp.__init__(self, width, height)
+
+ # empty the palette
+ self.palette = []
+
+
+class bitmap_1bpp_palettetoobig(bitmap_1bpp):
+ "A bitmap that has 1 bit per pixel that has a palette with 5000 colors."
+
+ def __init__(self, width, height):
+ bitmap_1bpp.__init__(self, width, height)
+
+ for i in range(0,5000):
+ self.palette.append(i)
+
+class bitmap_1bpp_croppedpixeldata(bitmap_1bpp):
+ """
+ A 1 bpp bitmap that ends in the middle of the pixel data.
+ This tests that what happens when a call to fread() fails.
+ This bitmap processor should probably process the data that
+ it does have AND display a diagnostic.
+ """
+
+ def write(self, filename):
+ self.write_croppped_bitmap(filename)
+
+
+class bitmap_width_height_overflow(bitmap_565):
+ """
+ A bitmap whose reported width and height cause a 32bit overflow when
+ they are multiplied together.
+ This tries to trick the image processor into allocating a very small
+ buffer that it thinks is very large.
+ """
+
+ def get_width(self):
+ return 0x10000
+
+ def get_height(self):
+ return 0x10000
+
+class bitmap_emptyfile(bitmap_1bpp):
+ """
+ A zero-byte file.
+ This tests that what happens when the first call to fread() fails.
+ """
+
+ def write(self, filename):
+
+ _safe_unlink(filename)
+
+ bmpfile = open(filename, 'wb')
+ bmpfile.close()
+
+class bitmap_badmagicnumber(bitmap_1bpp):
+ """
+ A bitmap with an invalid magic number (it uses 'Bm' instead of 'BM')
+ A bitmap processor that ignores this field is probably trusting the file extension
+ or doing a case-insensitive compare.
+ """
+
+ def get_magic_number(self):
+ "return the bad magic number"
+ return 'Bm'
+
+
+class bitmap_croppedmagicnumber(bitmap_1bpp):
+ """
+ A one byte bitmap that only contains the 'B' of the magic number.
+ This tests that what happens when the first call to fread() returns
+ fewer bytes than expected.
+ """
+
+ def write(self, filename):
+
+ _safe_unlink(filename)
+
+ bmpfile = open(filename, 'wb')
+ bmpfile.write('B')
+ bmpfile.close()
+
+class bitmap_badfilesize(bitmap_1bpp):
+ """
+ A bitmap with a filesize that's half of what it should be.
+ Most bitmap processors ignore this field.
+ """
+
+ def get_filesize(self):
+ "Return a filesize that is half of what it should be"
+ return bitmap_1bpp.get_filesize(self) / 2
+
+
+class bitmap_zerofilesize(bitmap_1bpp):
+ """
+ A bitmap with an filesize of 0.
+ Most bitmap processors ignore this field.
+ """
+
+ def get_filesize(self):
+ return 0
+
+class bitmap_badreserved1(bitmap_1bpp):
+ """
+ A bitmap with an 'wReserved1' field that is not 0.
+ This is technically illegal, but most bitmap processors ignore this field.
+ """
+
+ def get_reserved1(self):
+ return 1
+
+class bitmap_badreserved2(bitmap_1bpp):
+ """
+ A bitmap with an 'wReserved2' field that is not 0.
+ This is technically illegal, but most bitmap processors ignore this field.
+ """
+
+ def get_reserved2(self):
+ return 1
+
+class bitmap_negativeoffbits(bitmap_1bpp):
+ """
+ A bitmap with an 'dwOffBits' field that is -1.
+ This is supposed to be interpreted as an unsigned value, so it will
+ either be understood as a very large (illegal) value,
+ or a negative value (also illegal).
+ """
+
+ def get_offset_of_bitmap_data(self):
+ return -1
+
+class bitmap_largeoffbits(bitmap_1bpp):
+ """
+ A bitmap with an 'dwOffBits' field that is larger than the file size.
+ """
+
+ def get_offset_of_bitmap_data(self):
+ return self.get_filesize() + 1
+
+
+class bitmap_zerooffbits(bitmap_1bpp):
+ """
+ A bitmap with an 'dwOffBits' field that is 0.
+ A bitmap processor may recover from this by assuming that the pixel data
+ immediately follows the palette.
+ """
+
+ def get_offset_of_bitmap_data(self):
+ return 0
+
+class bitmap_croppedfileinfoheader(bitmap_1bpp):
+ """
+ A bitmap that is one byte short of having a complete fileinfoheader.
+ This tests that what happens when fread() returns fewer bytes
+ than expected.
+ """
+
+ def write(self, filename):
+
+ _safe_unlink(filename)
+
+ bmpfile = open(filename, 'wb')
+
+ fileinfoheader = self.get_fileinfoheader()
+
+ # remove the last byte of the FILEINFOHEADER
+ content = fileinfoheader[0 : len(fileinfoheader) - 1]
+ bmpfile.write(content)
+
+ # don't write anything else.
+ bmpfile.close()
+
+class bitmap_missinginfoheader(bitmap_1bpp):
+ """
+ A bitmap file that is so short that it doesn't include a BITMAPINFOHEADER.
+ This tests that what happens when a call to fread() fails.
+ """
+
+ def write(self, filename):
+
+ _safe_unlink(filename)
+
+ bmpfile = open(filename, 'wb')
+
+ fileinfoheader = self.get_fileinfoheader()
+ bmpfile.write(fileinfoheader)
+
+ # don't write any other part of the bitmap
+ bmpfile.close()
+
+class bitmap_croppedinfoheader(bitmap_1bpp):
+ """
+ A bitmap that is one byte short of having a complete BITMAPINFOHEADER.
+ This tests that what happens when fread() returns fewer bytes
+ than expected.
+ """
+
+ def write(self, filename):
+
+ _safe_unlink(filename)
+
+ bmpfile = open(filename, 'wb')
+
+ fileinfoheader = self.get_fileinfoheader()
+ bmpfile.write(fileinfoheader)
+
+ bmpinfoheader = self.get_bitmapinfoheader()
+
+ # remove the last byte of the BITMAPINFOHEADER
+ content = bmpinfoheader[0 : len(bmpinfoheader) - 1]
+ bmpfile.write(content)
+
+ # don't write any other part of the bitmap
+ bmpfile.close()
+
+class bitmap_smallbmpinfoheadersize(bitmap_1bpp):
+ """
+ A bitmap with a 'biSize' field in its BMPINFOHEADER that is too small.
+ """
+
+ def get_bitmap_info_header_size(self):
+ return 24
+
+ def get_bitmapinfoheader(self):
+ "Return the short BITMAPINFOHEADER"
+
+ size = self.get_bitmap_info_header_size()
+ width = self.get_width()
+ height = self.get_height()
+ planes = self.get_planes()
+ bits_per_pixel = self.get_bits_per_pixel()
+ compression = self.get_compression()
+ image_size = self.get_image_size()
+
+ bitmapinfoheader = struct.pack(
+ '<IiihhII',
+ size,
+ width,
+ height,
+ planes,
+ bits_per_pixel,
+ compression,
+ image_size)
+
+ return bitmapinfoheader
+
+class bitmap_largebmpinfoheadersize(bitmap_1bpp):
+ """
+ A bitmap with a 'biSize' field in its BMPINFOHEADER that is too large.
+ """
+
+ def get_bitmap_info_header_size(self):
+ return 64 * 1024 * 1024
+
+class bitmap_zerobmpinfoheadersize(bitmap_1bpp):
+ """
+ A bitmap with a 'biSize' field in its BMPINFOHEADER that is 0.
+ """
+
+ def get_bitmap_info_header_size(self):
+ return 0
+
+
+class bitmap_zeroheight(bitmap_1bpp):
+ """
+ A bitmap with a 'biHeight' field in its BMPINFOHEADER that is 0.
+ """
+
+ def get_height(self):
+ return 0
+
+class bitmap_zerowidth(bitmap_1bpp):
+ """
+ A bitmap with a 'biWidth' field in its BMPINFOHEADER that is 0.
+ """
+
+ def get_width(self):
+ return 0
+
+class bitmap_negativewidth(bitmap_1bpp):
+ """
+ A bitmap with a negative 'biWidth' field in its BMPINFOHEADER.
+ """
+
+ def get_width(self):
+ return -self.width
+
+class bitmap_zeroplanes(bitmap_1bpp):
+ """
+ A bitmap with a 'biPlanes' field in its BMPINFOHEADER that is zero.
+ This is an invalid bitmap, but many bitmap processors ignore this field.
+ """
+
+ def get_planes(self):
+ return 0
+
+class bitmap_largeplanes(bitmap_1bpp):
+ """
+ A bitmap with a 'biPlanes' field in its BMPINFOHEADER that is large.
+ This is an invalid bitmap, but many bitmap processors ignore this field.
+ """
+
+ def get_planes(self):
+ return 5000
+
+
+class bitmap_oddbitdepth(bitmap_8bpp):
+ """
+ A bitmap with a 'biBitCount' field in its BMPINFOHEADER that is odd.
+ """
+
+ def get_bits_per_pixel(self):
+ return 7
+
+class bitmap_zerobitdepth(bitmap_1bpp):
+ """
+ A bitmap with a 'biBitCount' field in its BMPINFOHEADER that is 0.
+ """
+
+ def get_bits_per_pixel(self):
+ return 0
+
+class bitmap_largebitdepth(bitmap_1bpp):
+ """
+ A bitmap with a 'biBitCount' field in its BMPINFOHEADER that is very large.
+ This attempts to trick the bitmap processor into thinking the bit depth is negative.
+ """
+
+ def get_bits_per_pixel(self):
+ return 0xFFFF
+
+class bitmap_unknowncompression(bitmap_1bpp):
+ """
+ A bitmap with an unrecognized 'biCompression' field.
+ """
+
+ def get_compression(self):
+ return 0xFFFFFFFF
+
+class bitmap_4bpp_rle8compression(bitmap_rle4_encoded):
+ """
+ A 4 bpp bitmap with a 'biCompression' field of BI_RLE8.
+ Only 8 bpp bitmaps may use BI_RLE8.
+ """
+
+ def get_compression(self):
+ return self.BI_RLE8
+
+
+class bitmap_8bpp_rle4compression(bitmap_rle8_encoded):
+ """
+ An 8 bpp bitmap with a 'biCompression' field of BI_RLE4.
+ Only 4 bpp bitmaps may use BI_RLE4.
+ """
+
+ def get_compression(self):
+ return self.BI_RLE4
+
+class bitmap_8bpp_zeroxpelspermeter(bitmap_8bpp):
+ """
+ An 8 bpp bitmap with a 'biXPelsPerMeter' field of 0.
+ Most bitmap processors ignore this field, but it is most likely used when
+ printing the image.
+ """
+
+ def get_pixels_per_meter_x(self):
+ "Return the biXPelsPerMeter to put into the BITMAPINFOHEADER"
+ return 0
+
+class bitmap_8bpp_negativexpelspermeter(bitmap_8bpp):
+ """
+ An 8 bpp bitmap with a negative 'biXPelsPerMeter' field.
+ Most bitmap processors ignore this field, but it is most likely used when
+ printing the image.
+ """
+
+ def get_pixels_per_meter_x(self):
+ "Return the biXPelsPerMeter to put into the BITMAPINFOHEADER"
+ return -10000
+
+class bitmap_8bpp_largexpelspermeter(bitmap_8bpp):
+ """
+ An 8 bpp bitmap with a large 'biXPelsPerMeter' field.
+ Most bitmap processors ignore this field, but it is most likely used when
+ printing the image.
+ """
+
+ def get_pixels_per_meter_x(self):
+ "Return the biXPelsPerMeter to put into the BITMAPINFOHEADER"
+ return 0x7FFFFFFF
+
+class bitmap_8bpp_zeroypelspermeter(bitmap_8bpp):
+ """
+ An 8 bpp bitmap with a 'biYPelsPerMeter' field of 0.
+ Most bitmap processors ignore this field, but it is most likely used when
+ printing the image.
+ """
+
+ def get_pixels_per_meter_y(self):
+ "Return the biYPelsPerMeter to put into the BITMAPINFOHEADER"
+ return 0
+
+class bitmap_8bpp_negativeypelspermeter(bitmap_8bpp):
+ """
+ An 8 bpp bitmap with a negative 'biYPelsPerMeter' field.
+ Most bitmap processors ignore this field, but it is most likely used when
+ printing the image.
+ """
+
+ def get_pixels_per_meter_y(self):
+ "Return the biYPelsPerMeter to put into the BITMAPINFOHEADER"
+ return -10000
+
+class bitmap_8bpp_largeypelspermeter(bitmap_8bpp):
+ """
+ An 8 bpp bitmap with a large 'biYPelsPerMeter' field.
+ Most bitmap processors ignore this field, but it is most likely used when
+ printing the image.
+ """
+
+ def get_pixels_per_meter_y(self):
+ "Return the biYPelsPerMeter to put into the BITMAPINFOHEADER"
+ return 0x7FFFFFF
+
+
+
+class bitmap_missingpalette(bitmap_1bpp):
+ """
+ A bitmap file that is so short that it doesn't include the palette.
+ This tests that what happens when a call to fread() fails.
+ """
+
+ def write(self, filename):
+
+ _safe_unlink(filename)
+
+ bmpfile = open(filename, 'wb')
+
+ fileinfoheader = self.get_fileinfoheader()
+ bmpfile.write(fileinfoheader)
+
+ bmpinfoheader = self.get_bitmapinfoheader()
+ bmpfile.write(bmpinfoheader)
+
+ # don't write any other part of the bitmap
+ bmpfile.close()
+
+class bitmap_croppedpalette(bitmap_1bpp):
+ """
+ A bitmap that is one byte short of having a complete palette.
+ This tests that what happens when fread() returns fewer bytes
+ than expected.
+ """
+
+ def write(self, filename):
+
+ _safe_unlink(filename)
+
+ bmpfile = open(filename, 'wb')
+
+ fileinfoheader = self.get_fileinfoheader()
+ bmpfile.write(fileinfoheader)
+
+ bmpinfoheader = self.get_bitmapinfoheader()
+ bmpfile.write(bmpinfoheader)
+
+ palette = self.get_palette()
+
+ # remove the last byte of the BITMAPINFOHEADER
+ content = palette[0 : len(palette) - 1]
+ bmpfile.write(content)
+
+ # don't write any other part of the bitmap
+ bmpfile.close()
+
+class bitmap_missingcolormasks(bitmap_565):
+ """
+ A BI_BITFIELDS bitmap file that is so short that it doesn't include the
+ colormask array.
+ This tests that what happens when a call to fread() fails.
+ """
+
+ def write(self, filename):
+
+ _safe_unlink(filename)
+
+ bmpfile = open(filename, 'wb')
+
+ fileinfoheader = self.get_fileinfoheader()
+ bmpfile.write(fileinfoheader)
+
+ bmpinfoheader = self.get_bitmapinfoheader()
+ bmpfile.write(bmpinfoheader)
+
+ # don't write any other part of the bitmap
+ bmpfile.close()
+
+class bitmap_croppedcolormasks(bitmap_565):
+ """
+ A BI_BITFIELDS bitmap that is one byte short of having a complete
+ colormask array.
+ This tests that what happens when fread() returns fewer bytes
+ than expected.
+ """
+
+ def write(self, filename):
+
+ _safe_unlink(filename)
+
+ bmpfile = open(filename, 'wb')
+
+ fileinfoheader = self.get_fileinfoheader()
+ bmpfile.write(fileinfoheader)
+
+ bmpinfoheader = self.get_bitmapinfoheader()
+ bmpfile.write(bmpinfoheader)
+
+ palette = self.get_palette()
+
+ # remove the last byte of the BITMAPINFOHEADER
+ content = palette[0 : len(palette) - 1]
+ bmpfile.write(content)
+
+ # don't write any other part of the bitmap
+ bmpfile.close()
+
+
+class bitmap_missingpixeldata(bitmap_24bpp):
+ """
+ A bitmap file that doesn't include any of the pixel data.
+ """
+
+ def write(self, filename):
+
+ _safe_unlink(filename)
+
+ bmpfile = open(filename, 'wb')
+
+ fileinfoheader = self.get_fileinfoheader()
+ bmpfile.write(fileinfoheader)
+
+ bmpinfoheader = self.get_bitmapinfoheader()
+ bmpfile.write(bmpinfoheader)
+
+ palette = self.get_palette()
+ bmpfile.write(palette)
+
+ # don't write any other part of the bitmap
+ bmpfile.close()
+
+class bitmap_toomuchdata(bitmap_1bpp):
+ """
+ A bitmap with twice as much payload as expected.
+ This attempts to overflow an internal buffer.
+ """
+
+ def create_pixeldata(self):
+ return bitmap_1bpp.create_pixeldata(self) * 2
+
+
+class testcase_logger:
+ def __init__(self, path):
+ # a map from filename to English description of the file.
+ self.descriptions = {}
+
+ # the file path to the directory containing the bitmap
+ self.path = path
+
+ def write_index(self, basename):
+ keys = self.descriptions.keys()
+ keys.sort()
+
+ index_filename = self.path + '/' + basename
+ _safe_unlink(index_filename)
+ indexfile = open(index_filename, 'wb')
+
+ indexfile.write('<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">n')
+ indexfile.write('<html>n')
+ indexfile.write(' <head>n')
+ indexfile.write(' <title>Directory Listing</title>n')
+ indexfile.write(' </head>n')
+ indexfile.write(' <body>n')
+ indexfile.write(' <table border="1">n')
+ indexfile.write('n')
+ indexfile.write(' <tr>n')
+ indexfile.write(' <th>Filename</th>n')
+ indexfile.write(' <th>Description</th>n')
+ indexfile.write(' </tr>n')
+ indexfile.write('n')
+
+ for key in keys:
+ indexfile.write(' <tr>n')
+ indexfile.write(' <td><a href="' + key + '">' + key + '</a></td>n')
+ indexfile.write(' <td>' + self.descriptions[key] + '</td>n')
+ indexfile.write(' </tr>n')
+ indexfile.write('n')
+
+ indexfile.write(' </table>n')
+ indexfile.write(' </body>n')
+ indexfile.write('</html>n')
+
+ indexfile.close()
+
+
+ def do_testcase(self, filename, bitmap, *rest):
+ bitmap.write(self.path + '/' + filename)
+
+ # Figure out the bitmap's English description.
+ # Start with the doc string and append the optional
+ # complementary description argument.
+ description = bitmap.__doc__
+ if len(rest) != 0:
+ description += ' ' + rest[0]
+
+ self.descriptions[filename] = description
+
+def generate_valid_bitmaps():
+ """
+ Create valid bitmaps of various encodings.
+ """
+
+ _safe_create_dir('bitmaps')
+ _safe_create_dir('bitmaps/valid')
+
+ log = testcase_logger('bitmaps/valid')
+
+ # valid 1 bpp bitmaps
+ for width in range(320,336):
+ log.do_testcase(
+ '1bpp-%ix240.bmp' % width,
+ bitmap_1bpp(width, 240),
+ 'Each scanline has %i bits of padding.' % (width - 320))
+
+ log.do_testcase(
+ '1bpp-1x1.bmp',
+ bitmap_1bpp(1, 1),
+ 'The image is a single black pixel.')
+
+ log.do_testcase(
+ '1bpp-320x240-color.bmp',
+ bitmap_1bpp_color(320, 240))
+
+ log.do_testcase(
+ '1bpp-320x240-overlappingcolor.bmp',
+ bitmap_1bpp_overlappingcolor(320, 240))
+
+ log.do_testcase(
+ '1bpp-topdown-320x240.bmp',
+ bitmap_1bpp_topdown(320, 240))
+
+ # valid 4 bpp bitmaps
+ for width in range(320,328):
+ log.do_testcase(
+ '4bpp-%ix240.bmp' % width,
+ bitmap_4bpp(width, 240),
+ 'Each scanline has %i nibbles of padding.' % (width - 320))
+
+ for width in range (320, 321):
+ log.do_testcase(
+ 'rle4-encoded-%ix240.bmp' % width,
+ bitmap_rle4_encoded(width, 240))
+
+ for width in range (320, 321):
+ log.do_testcase(
+ 'rle4-absolute-%ix240.bmp' % width,
+ bitmap_rle4_absolute(width, 240))
+
+ for width in range (320, 321):
+ log.do_testcase(
+ 'rle4-alternate-%ix240.bmp' % width,
+ bitmap_rle4_alternate(width, 240))
+
+ log.do_testcase(
+ 'rle4-delta-320x240.bmp',
+ bitmap_rle4_delta(320, 240))
+
+ log.do_testcase(
+ '4bpp-1x1.bmp',
+ bitmap_4bpp(1, 1),
+ 'The image is a single blue pixel.')
+
+ log.do_testcase(
+ '4bpp-topdown-320x240.bmp',
+ bitmap_4bpp_topdown(320, 240))
+
+
+ # valid 8 bpp bitmaps
+ for width in range(320,324):
+ log.do_testcase(
+ '8bpp-%ix240.bmp' % width,
+ bitmap_8bpp(width, 240),
+ 'Each scanline has %i bytes of padding.' % (width - 320))
+
+ for width in range (320, 321):
+ log.do_testcase(
+ 'rle8-encoded-%ix240.bmp' % width,
+ bitmap_rle8_encoded(width, 240))
+
+ for width in range (320, 321):
+ log.do_testcase(
+ 'rle8-absolute-%ix240.bmp' % width,
+ bitmap_rle8_absolute(width, 240))
+
+ log.do_testcase(
+ 'rle8-delta-320x240.bmp',
+ bitmap_rle8_delta(320, 240))
+
+ log.do_testcase(
+ 'rle8-blank-160x120.bmp',
+ bitmap_rle8_blank(160, 120))
+
+ log.do_testcase(
+ '8bpp-1x1.bmp',
+ bitmap_8bpp(1, 1),
+ 'The image is a single blue pixel.')
+
+ log.do_testcase(
+ 'rle8-64000x1.bmp',
+ bitmap_rle8_encoded(64000, 1),
+ 'The image is a very long red, green, and blue horizontal line.')
+
+ log.do_testcase(
+ '8bpp-1x64000.bmp',
+ bitmap_8bpp(1, 64000),
+ 'The image is a very long, blue vertical line.')
+
+ log.do_testcase(
+ '8bpp-colorsused-zero.bmp',
+ bitmap_8bpp_zerocolorsused(320, 240))
+
+ log.do_testcase(
+ '8bpp-colorsimportant-two.bmp',
+ bitmap_8bpp_twocolorsimportant(320, 240))
+
+ log.do_testcase(
+ '8bpp-topdown-320x240.bmp',
+ bitmap_8bpp_topdown(320, 240))
+
+ # valid 5-5-5 bitmaps
+ for width in range(320,322):
+ log.do_testcase(
+ '555-%ix240.bmp' % width,
+ bitmap_555(width, 240),
+ 'Each scanline has %i bytes of padding.' % ((width - 320) / 2))
+
+ log.do_testcase(
+ '555-1x1.bmp',
+ bitmap_555(1, 1),
+ 'The image is a single blue pixel.')
+
+ # valid 5-6-5 bitmaps
+ for width in range(320,323):
+ log.do_testcase(
+ '565-%ix240.bmp' % width,
+ bitmap_565(width, 240),
+ 'Each scanline has %i bytes of padding.' % ((width - 320) / 2))
+
+ log.do_testcase(
+ '565-%ix240-topdown.bmp' % width,
+ bitmap_565_topdown(width, 240),
+ 'Each scanline has %i bytes of padding.' % ((width - 320) / 2))
+
+ log.do_testcase(
+ '565-1x1.bmp',
+ bitmap_565(1, 1),
+ 'The image is a single blue pixel.')
+
+
+ # valid 24 bpp bitmaps
+ for width in range(320,324):
+ log.do_testcase(
+ '24bpp-%ix240.bmp' % width,
+ bitmap_24bpp(width, 240),
+ 'Each scanline has %i bytes of padding.' % ((width - 320) / 3))
+
+ log.do_testcase(
+ '24bpp-topdown-320x240.bmp',
+ bitmap_24bpp_topdown(320, 240))
+
+ log.do_testcase(
+ '24bpp-1x1.bmp',
+ bitmap_24bpp(1, 1),
+ 'The image is a single blue pixel.')
+
+ log.do_testcase(
+ '24bpp-imagesize-zero.bmp',
+ bitmap_24bpp_zeroimagesize(320, 240))
+
+ # valid 32 bpp bitmaps
+ log.do_testcase(
+ '32bpp-320x240.bmp',
+ bitmap_32bpp(320, 240))
+
+ log.do_testcase(
+ '32bpp-topdown-320x240.bmp',
+ bitmap_32bpp_topdown(320, 240))
+
+ log.do_testcase(
+ '32bpp-optimalpalette-320x240.bmp',
+ bitmap_32bpp_colortable(320, 240))
+
+ log.do_testcase(
+ '32bpp-888-optimalpalette-320x240.bmp',
+ bitmap_32bpp_888_colortable(320, 240))
+
+ log.do_testcase(
+ '32bpp-101110-320x240.bmp',
+ bitmap_32bpp_101110(320, 240))
+
+ log.do_testcase(
+ '32bpp-1x1.bmp',
+ bitmap_32bpp(1, 1),
+ 'The image is a single blue pixel.')
+
+ # write out the HTML index
+ log.write_index('index.html')
+
+
+def generate_questionable_bitmaps():
+ """
+ Create bitmaps that are technically invalid, but which most
+ bitmap processors can process, anyway.
+ """
+
+ _safe_create_dir('bitmaps')
+ _safe_create_dir('bitmaps/questionable')
+
+ log = testcase_logger('bitmaps/questionable')
+
+ log.do_testcase(
+ 'filesize-bad.bmp',
+ bitmap_badfilesize(320, 240))
+
+ log.do_testcase(
+ 'filesize-zero.bmp',
+ bitmap_zerofilesize(320, 240))
+
+ log.do_testcase(
+ 'reserved1-bad.bmp',
+ bitmap_badreserved1(320, 240))
+
+ log.do_testcase(
+ 'reserved2-bad.bmp',
+ bitmap_badreserved2(320, 240))
+
+ log.do_testcase(
+ 'rle8-height-negative.bmp',
+ bitmap_rle8_topdown(320, 240))
+
+ log.do_testcase(
+ 'rle4-height-negative.bmp',
+ bitmap_rle4_topdown(320, 240))
+
+ log.do_testcase(
+ 'planes-zero.bmp',
+ bitmap_zeroplanes(320, 240))
+
+ log.do_testcase(
+ 'planes-large.bmp',
+ bitmap_largeplanes(320, 240))
+
+ log.do_testcase(
+ 'pels-per-meter-x-zero.bmp',
+ bitmap_8bpp_zeroxpelspermeter(320, 240))
+
+ log.do_testcase(
+ 'pels-per-meter-x-negative.bmp',
+ bitmap_8bpp_negativexpelspermeter(320, 240))
+
+ log.do_testcase(
+ 'pels-per-meter-x-large.bmp',
+ bitmap_8bpp_largexpelspermeter(320, 240))
+
+ log.do_testcase(
+ 'pels-per-meter-y-zero.bmp',
+ bitmap_8bpp_zeroypelspermeter(320, 240))
+
+ log.do_testcase(
+ 'pels-per-meter-y-negative.bmp',
+ bitmap_8bpp_negativeypelspermeter(320, 240))
+
+ log.do_testcase(
+ 'pels-per-meter-y-large.bmp',
+ bitmap_8bpp_largeypelspermeter(320, 240))
+
+ log.do_testcase(
+ 'pixeldata-toomuch.bmp',
+ bitmap_toomuchdata(320, 240))
+
+ log.do_testcase(
+ 'pixeldata-rle8-toomuch.bmp',
+ bitmap_rle8_toomuchdata(320, 240))
+
+ log.do_testcase(
+ 'rle8-no-end-of-bitmap-marker.bmp',
+ bitmap_rle8_noendofbitmap(320, 240))
+
+ log.do_testcase(
+ '8bpp-pixels-not-in-palette.bmp',
+ bitmap_8bpp_pixelnotinpalette(254, 128))
+
+ log.do_testcase(
+ '32bpp-0x0.bmp',
+ bitmap_32bpp(0, 0),
+ 'The image is 0 pixels wide and 0 pixels high. Even though this is technically valid, most bitmap procesors consider it to be corrupt.')
+
+ log.do_testcase(
+ '32bpp-320x0.bmp',
+ bitmap_32bpp(320, 0),
+ 'The image is 320 pixels wide and zero pixels high. This is a sneaky way of making a 0x0 bitmap. Even though this is technically valid, most bitmap procesors consider it to be corrupt.')
+
+ log.do_testcase(
+ '32bpp-0x240.bmp',
+ bitmap_32bpp(0, 240),
+ 'The image is 0 pixels wide and 240 pixels high. This is a sneaky way of making a 0x0 bitmap. Even though this is technically valid, most bitmap procesors consider it to be corrupt.')
+
+ log.do_testcase(
+ 'rle4-no-end-of-bitmap-marker.bmp',
+ bitmap_rle4_noendofbitmap(320, 240))
+
+ # write out the HTML index
+ log.write_index('index.html')
+
+
+
+def generate_corrupt_bitmaps():
+ """
+ Create corrupt/malicious bitmaps that are either impossible to process,
+ or that most bitmap processors will refuse to process.
+ For most of these files, the best a bitmap processor can do is
+ display an informative diagnostic and not crash or leak memory.
+ """
+
+ _safe_create_dir('bitmaps')
+ _safe_create_dir('bitmaps/corrupt')
+
+ log = testcase_logger('bitmaps/corrupt')
+
+ # invalid images
+ log.do_testcase(
+ 'emptyfile.bmp',
+ bitmap_emptyfile(320, 240))
+
+ log.do_testcase(
+ 'fileinfoheader-cropped.bmp',
+ bitmap_croppedfileinfoheader(320, 240))
+
+ log.do_testcase(
+ 'magicnumber-cropped.bmp',
+ bitmap_croppedmagicnumber(320, 240))
+
+ log.do_testcase(
+ 'magicnumber-bad.bmp',
+ bitmap_badmagicnumber(320, 240))
+
+ log.do_testcase(
+ 'offbits-zero.bmp',
+ bitmap_zerooffbits(320, 240))
+
+ log.do_testcase(
+ 'offbits-negative.bmp',
+ bitmap_negativeoffbits(320, 240))
+
+ log.do_testcase(
+ 'offbits-large.bmp',
+ bitmap_largeoffbits(320, 240))
+
+ log.do_testcase(
+ 'infoheader-missing.bmp',
+ bitmap_missinginfoheader(320, 240))
+
+ log.do_testcase(
+ 'infoheader-cropped.bmp',
+ bitmap_croppedinfoheader(320, 240))
+
+ log.do_testcase(
+ 'infoheadersize-small.bmp',
+ bitmap_smallbmpinfoheadersize(320, 240))
+
+ log.do_testcase(
+ 'infoheadersize-large.bmp',
+ bitmap_largebmpinfoheadersize(320, 240))
+
+ log.do_testcase(
+ 'infoheadersize-zero.bmp',
+ bitmap_zerobmpinfoheadersize(320, 240))
+
+ log.do_testcase(
+ 'height-zero.bmp',
+ bitmap_zeroheight(320, 240))
+
+ log.do_testcase(
+ 'width-zero.bmp',
+ bitmap_zerowidth(320, 240))
+
+ log.do_testcase(
+ 'width-negative.bmp',
+ bitmap_negativewidth(320, 240))
+
+ log.do_testcase(
+ 'width-times-height-overflow.bmp',
+ bitmap_width_height_overflow(320, 240))
+
+ log.do_testcase(
+ 'bitdepth-zero.bmp',
+ bitmap_zerobitdepth(320, 240))
+
+ log.do_testcase(
+ 'bitdepth-odd.bmp',
+ bitmap_oddbitdepth(320, 240))
+
+ log.do_testcase(
+ 'bitdepth-large.bmp',
+ bitmap_largebitdepth(320, 240))
+
+ log.do_testcase(
+ 'compression-unknown.bmp',
+ bitmap_unknowncompression(320, 240))
+
+ log.do_testcase(
+ 'compression-bad-rle4-for-8bpp.bmp',
+ bitmap_4bpp_rle8compression(320, 240))
+
+ log.do_testcase(
+ 'compression-bad-rle8-for-4bpp.bmp',
+ bitmap_8bpp_rle4compression(320, 240))
+
+ log.do_testcase(
+ '8bpp-colorsused-large.bmp',
+ bitmap_8bpp_largecolorsused(320, 240))
+
+ log.do_testcase(
+ '8bpp-colorsused-negative.bmp',
+ bitmap_8bpp_negativecolorsused(320, 240))
+
+ log.do_testcase(
+ '8bpp-colorsimportant-large.bmp',
+ bitmap_8bpp_largecolorsimportant(320, 240))
+
+ log.do_testcase(
+ '8bpp-colorsimportant-negative.bmp',
+ bitmap_8bpp_negativecolorsimportant(320, 240))
+
+ log.do_testcase(
+ 'rle8-deltaleavesimage.bmp',
+ bitmap_rle8_deltaleavesimage(320, 240))
+
+ log.do_testcase(
+ 'palette-too-big.bmp',
+ bitmap_1bpp_palettetoobig(320, 240))
+
+ log.do_testcase(
+ '1bpp-no-palette.bmp',
+ bitmap_1bpp_nopalette(320, 240))
+
+ log.do_testcase(
+ '4bpp-no-palette.bmp',
+ bitmap_4bpp_nopalette(320, 240))
+
+ log.do_testcase(
+ '8bpp-no-palette.bmp',
+ bitmap_8bpp_nopalette(320, 240))
+
+ log.do_testcase(
+ 'palette-missing.bmp',
+ bitmap_missingpalette(320, 240))
+
+ log.do_testcase(
+ 'palette-cropped.bmp',
+ bitmap_croppedpalette(320, 240))
+
+ log.do_testcase(
+ 'colormasks-missing.bmp',
+ bitmap_missingcolormasks(320, 240))
+
+ log.do_testcase(
+ 'colormasks-cropped.bmp',
+ bitmap_croppedcolormasks(320, 240))
+
+ log.do_testcase(
+ 'pixeldata-missing.bmp',
+ bitmap_missingpixeldata(320, 240))
+
+ log.do_testcase(
+ '32bpp-pixeldata-cropped.bmp',
+ bitmap_32bpp_croppedpixeldata(320, 240))
+
+ log.do_testcase(
+ '24bpp-pixeldata-cropped.bmp',
+ bitmap_24bpp_croppedpixeldata(320, 240))
+
+ log.do_testcase(
+ '555-pixeldata-cropped.bmp',
+ bitmap_555_croppedpixeldata(320, 240))
+
+ log.do_testcase(
+ '8bpp-pixeldata-cropped.bmp',
+ bitmap_8bpp_croppedpixeldata(320, 240))
+
+ log.do_testcase(
+ '4bpp-pixeldata-cropped.bmp',
+ bitmap_4bpp_croppedpixeldata(320, 240))
+
+ log.do_testcase(
+ '1bpp-pixeldata-cropped.bmp',
+ bitmap_1bpp_croppedpixeldata(320, 240))
+
+ log.do_testcase(
+ 'rle4-runlength-cropped.bmp',
+ bitmap_rle4_croppedrun(320, 240))
+
+ log.do_testcase(
+ 'rle4-absolute-cropped.bmp',
+ bitmap_rle4_croppedabsolute(320, 240))
+
+ log.do_testcase(
+ 'rle4-delta-cropped.bmp',
+ bitmap_rle4_croppeddelta(320, 240))
+
+ log.do_testcase(
+ 'rle4-no-end-of-line-marker.bmp',
+ bitmap_rle4_noendofline(320, 240))
+
+ log.do_testcase(
+ 'rle8-runlength-cropped.bmp',
+ bitmap_rle8_croppedrun(320, 240))
+
+ log.do_testcase(
+ 'rle8-absolute-cropped.bmp',
+ bitmap_rle8_croppedabsolute(320, 240))
+
+ log.do_testcase(
+ 'rle8-delta-cropped.bmp',
+ bitmap_rle8_croppeddelta(320, 240))
+
+ log.do_testcase(
+ 'rle8-no-end-of-line-marker.bmp',
+ bitmap_rle8_noendofline(320, 240))
+
+ # write out the HTML index
+ log.write_index('index.html')
+
+if __name__ == "__main__":
+
+ generate_valid_bitmaps()
+ generate_questionable_bitmaps()
+ generate_corrupt_bitmaps()
-----------------------------------------------------------------------
Summary of changes:
tests/Makefile | 1 +
tests/loaders/Makefile | 2 +-
tests/loaders/data/bmp/README | 4 +
.../data/bmp/bitmaps/corrupt/1bpp-no-palette.bmp | Bin 0 -> 9654 bytes
.../bmp/bitmaps/corrupt/1bpp-pixeldata-cropped.bmp | Bin 0 -> 4841 bytes
.../bitmaps/corrupt/24bpp-pixeldata-cropped.bmp | Bin 0 -> 114773 bytes
.../bitmaps/corrupt/32bpp-pixeldata-cropped.bmp | Bin 0 -> 153013 bytes
.../data/bmp/bitmaps/corrupt/4bpp-no-palette.bmp | Bin 0 -> 38454 bytes
.../bmp/bitmaps/corrupt/4bpp-pixeldata-cropped.bmp | Bin 0 -> 19197 bytes
.../bmp/bitmaps/corrupt/555-pixeldata-cropped.bmp | Bin 0 -> 76533 bytes
.../bitmaps/corrupt/8bpp-colorsimportant-large.bmp | Bin 0 -> 76878 bytes
.../corrupt/8bpp-colorsimportant-negative.bmp | Bin 0 -> 76878 bytes
.../bmp/bitmaps/corrupt/8bpp-colorsused-large.bmp | Bin 0 -> 76878 bytes
.../bitmaps/corrupt/8bpp-colorsused-negative.bmp | Bin 0 -> 76878 bytes
.../data/bmp/bitmaps/corrupt/8bpp-no-palette.bmp | Bin 0 -> 76854 bytes
.../bmp/bitmaps/corrupt/8bpp-pixeldata-cropped.bmp | Bin 0 -> 38317 bytes
.../data/bmp/bitmaps/corrupt/bitdepth-large.bmp | Bin 0 -> 9662 bytes
.../data/bmp/bitmaps/corrupt/bitdepth-odd.bmp | Bin 0 -> 76878 bytes
.../data/bmp/bitmaps/corrupt/bitdepth-zero.bmp | Bin 0 -> 9662 bytes
.../bmp/bitmaps/corrupt/colormasks-cropped.bmp | Bin 0 -> 65 bytes
.../bmp/bitmaps/corrupt/colormasks-missing.bmp | Bin 0 -> 54 bytes
.../corrupt/compression-bad-rle4-for-8bpp.bmp | Bin 0 -> 4134 bytes
.../corrupt/compression-bad-rle8-for-4bpp.bmp | Bin 0 -> 4134 bytes
.../bmp/bitmaps/corrupt/compression-unknown.bmp | Bin 0 -> 9662 bytes
.../bmp/bitmaps/corrupt/fileinfoheader-cropped.bmp | Bin 0 -> 13 bytes
.../data/bmp/bitmaps/corrupt/height-zero.bmp | Bin 0 -> 9662 bytes
tests/loaders/data/bmp/bitmaps/corrupt/index.html | 444 +++
.../bmp/bitmaps/corrupt/infoheader-cropped.bmp | Bin 0 -> 53 bytes
.../bmp/bitmaps/corrupt/infoheader-missing.bmp | Bin 0 -> 14 bytes
.../bmp/bitmaps/corrupt/infoheadersize-large.bmp | Bin 0 -> 9662 bytes
.../bmp/bitmaps/corrupt/infoheadersize-small.bmp | Bin 0 -> 9646 bytes
.../bmp/bitmaps/corrupt/infoheadersize-zero.bmp | Bin 0 -> 9662 bytes
.../data/bmp/bitmaps/corrupt/magicnumber-bad.bmp | Bin 0 -> 9662 bytes
.../bmp/bitmaps/corrupt/magicnumber-cropped.bmp | 1 +
.../data/bmp/bitmaps/corrupt/offbits-large.bmp | Bin 0 -> 9662 bytes
.../data/bmp/bitmaps/corrupt/offbits-negative.bmp | Bin 0 -> 9662 bytes
.../data/bmp/bitmaps/corrupt/offbits-zero.bmp | Bin 0 -> 9662 bytes
.../data/bmp/bitmaps/corrupt/palette-cropped.bmp | Bin 0 -> 61 bytes
.../data/bmp/bitmaps/corrupt/palette-missing.bmp | Bin 0 -> 54 bytes
.../data/bmp/bitmaps/corrupt/palette-too-big.bmp | Bin 0 -> 29662 bytes
.../data/bmp/bitmaps/corrupt/pixeldata-missing.bmp | Bin 0 -> 54 bytes
.../bmp/bitmaps/corrupt/rle4-absolute-cropped.bmp | Bin 0 -> 20367 bytes
.../bmp/bitmaps/corrupt/rle4-delta-cropped.bmp | Bin 0 -> 1781 bytes
.../bitmaps/corrupt/rle4-no-end-of-line-marker.bmp | Bin 0 -> 3654 bytes
.../bmp/bitmaps/corrupt/rle4-runlength-cropped.bmp | Bin 0 -> 1983 bytes
.../bmp/bitmaps/corrupt/rle8-absolute-cropped.bmp | Bin 0 -> 39695 bytes
.../bmp/bitmaps/corrupt/rle8-delta-cropped.bmp | Bin 0 -> 2741 bytes
.../bmp/bitmaps/corrupt/rle8-deltaleavesimage.bmp | Bin 0 -> 4138 bytes
.../bitmaps/corrupt/rle8-no-end-of-line-marker.bmp | Bin 0 -> 3654 bytes
.../bmp/bitmaps/corrupt/rle8-runlength-cropped.bmp | Bin 0 -> 1983 bytes
.../data/bmp/bitmaps/corrupt/width-negative.bmp | Bin 0 -> 9662 bytes
.../corrupt/width-times-height-overflow.bmp | Bin 0 -> 153666 bytes
.../data/bmp/bitmaps/corrupt/width-zero.bmp | Bin 0 -> 9662 bytes
.../data/bmp/bitmaps/questionable/32bpp-0x0.bmp | Bin 0 -> 54 bytes
.../data/bmp/bitmaps/questionable/32bpp-0x240.bmp | Bin 0 -> 54 bytes
.../data/bmp/bitmaps/questionable/32bpp-320x0.bmp | Bin 0 -> 54 bytes
.../questionable/8bpp-pixels-not-in-palette.bmp | Bin 0 -> 32830 bytes
.../data/bmp/bitmaps/questionable/filesize-bad.bmp | Bin 0 -> 9662 bytes
.../bmp/bitmaps/questionable/filesize-zero.bmp | Bin 0 -> 9662 bytes
.../data/bmp/bitmaps/questionable/index.html | 197 ++
.../questionable/pels-per-meter-x-large.bmp | Bin 0 -> 76878 bytes
.../questionable/pels-per-meter-x-negative.bmp | Bin 0 -> 76878 bytes
.../bitmaps/questionable/pels-per-meter-x-zero.bmp | Bin 0 -> 76878 bytes
.../questionable/pels-per-meter-y-large.bmp | Bin 0 -> 76878 bytes
.../questionable/pels-per-meter-y-negative.bmp | Bin 0 -> 76878 bytes
.../bitmaps/questionable/pels-per-meter-y-zero.bmp | Bin 0 -> 76878 bytes
.../questionable/pixeldata-rle8-toomuch.bmp | Bin 0 -> 8188 bytes
.../bmp/bitmaps/questionable/pixeldata-toomuch.bmp | Bin 0 -> 19262 bytes
.../data/bmp/bitmaps/questionable/planes-large.bmp | Bin 0 -> 9662 bytes
.../data/bmp/bitmaps/questionable/planes-zero.bmp | Bin 0 -> 9662 bytes
.../bmp/bitmaps/questionable/reserved1-bad.bmp | Bin 0 -> 9662 bytes
.../bmp/bitmaps/questionable/reserved2-bad.bmp | Bin 0 -> 9662 bytes
.../bitmaps/questionable/rle4-height-negative.bmp | Bin 0 -> 4134 bytes
.../questionable/rle4-no-end-of-bitmap-marker.bmp | Bin 0 -> 4132 bytes
.../bitmaps/questionable/rle8-height-negative.bmp | Bin 0 -> 4134 bytes
.../questionable/rle8-no-end-of-bitmap-marker.bmp | Bin 0 -> 4132 bytes
tests/loaders/data/bmp/bitmaps/valid/1bpp-1x1.bmp | Bin 0 -> 66 bytes
.../data/bmp/bitmaps/valid/1bpp-320x240-color.bmp | Bin 0 -> 9662 bytes
.../valid/1bpp-320x240-overlappingcolor.bmp | Bin 0 -> 9662 bytes
.../data/bmp/bitmaps/valid/1bpp-320x240.bmp | Bin 0 -> 9662 bytes
.../data/bmp/bitmaps/valid/1bpp-321x240.bmp | Bin 0 -> 10622 bytes
.../data/bmp/bitmaps/valid/1bpp-322x240.bmp | Bin 0 -> 10622 bytes
.../data/bmp/bitmaps/valid/1bpp-323x240.bmp | Bin 0 -> 10622 bytes
.../data/bmp/bitmaps/valid/1bpp-324x240.bmp | Bin 0 -> 10622 bytes
.../data/bmp/bitmaps/valid/1bpp-325x240.bmp | Bin 0 -> 10622 bytes
.../data/bmp/bitmaps/valid/1bpp-326x240.bmp | Bin 0 -> 10622 bytes
.../data/bmp/bitmaps/valid/1bpp-327x240.bmp | Bin 0 -> 10622 bytes
.../data/bmp/bitmaps/valid/1bpp-328x240.bmp | Bin 0 -> 10622 bytes
.../data/bmp/bitmaps/valid/1bpp-329x240.bmp | Bin 0 -> 10622 bytes
.../data/bmp/bitmaps/valid/1bpp-330x240.bmp | Bin 0 -> 10622 bytes
.../data/bmp/bitmaps/valid/1bpp-331x240.bmp | Bin 0 -> 10622 bytes
.../data/bmp/bitmaps/valid/1bpp-332x240.bmp | Bin 0 -> 10622 bytes
.../data/bmp/bitmaps/valid/1bpp-333x240.bmp | Bin 0 -> 10622 bytes
.../data/bmp/bitmaps/valid/1bpp-334x240.bmp | Bin 0 -> 10622 bytes
.../data/bmp/bitmaps/valid/1bpp-335x240.bmp | Bin 0 -> 10622 bytes
.../bmp/bitmaps/valid/1bpp-topdown-320x240.bmp | Bin 0 -> 9662 bytes
tests/loaders/data/bmp/bitmaps/valid/24bpp-1x1.bmp | Bin 0 -> 58 bytes
.../data/bmp/bitmaps/valid/24bpp-320x240.bmp | Bin 0 -> 230454 bytes
.../data/bmp/bitmaps/valid/24bpp-321x240.bmp | Bin 0 -> 231414 bytes
.../data/bmp/bitmaps/valid/24bpp-322x240.bmp | Bin 0 -> 232374 bytes
.../data/bmp/bitmaps/valid/24bpp-323x240.bmp | Bin 0 -> 233334 bytes
.../bmp/bitmaps/valid/24bpp-imagesize-zero.bmp | Bin 0 -> 230454 bytes
.../bmp/bitmaps/valid/24bpp-topdown-320x240.bmp | Bin 0 -> 230454 bytes
.../bmp/bitmaps/valid/32bpp-101110-320x240.bmp | Bin 0 -> 307266 bytes
tests/loaders/data/bmp/bitmaps/valid/32bpp-1x1.bmp | Bin 0 -> 58 bytes
.../data/bmp/bitmaps/valid/32bpp-320x240.bmp | Bin 0 -> 307254 bytes
.../valid/32bpp-888-optimalpalette-320x240.bmp | Bin 0 -> 307290 bytes
.../bitmaps/valid/32bpp-optimalpalette-320x240.bmp | Bin 0 -> 307278 bytes
.../bmp/bitmaps/valid/32bpp-topdown-320x240.bmp | Bin 0 -> 307254 bytes
tests/loaders/data/bmp/bitmaps/valid/4bpp-1x1.bmp | Bin 0 -> 82 bytes
.../data/bmp/bitmaps/valid/4bpp-320x240.bmp | Bin 0 -> 38478 bytes
.../data/bmp/bitmaps/valid/4bpp-321x240.bmp | Bin 0 -> 39438 bytes
.../data/bmp/bitmaps/valid/4bpp-322x240.bmp | Bin 0 -> 39438 bytes
.../data/bmp/bitmaps/valid/4bpp-323x240.bmp | Bin 0 -> 39438 bytes
.../data/bmp/bitmaps/valid/4bpp-324x240.bmp | Bin 0 -> 39438 bytes
.../data/bmp/bitmaps/valid/4bpp-325x240.bmp | Bin 0 -> 39438 bytes
.../data/bmp/bitmaps/valid/4bpp-326x240.bmp | Bin 0 -> 39438 bytes
.../data/bmp/bitmaps/valid/4bpp-327x240.bmp | Bin 0 -> 39438 bytes
.../bmp/bitmaps/valid/4bpp-topdown-320x240.bmp | Bin 0 -> 38478 bytes
tests/loaders/data/bmp/bitmaps/valid/555-1x1.bmp | Bin 0 -> 58 bytes
.../loaders/data/bmp/bitmaps/valid/555-320x240.bmp | Bin 0 -> 153654 bytes
.../loaders/data/bmp/bitmaps/valid/555-321x240.bmp | Bin 0 -> 154614 bytes
tests/loaders/data/bmp/bitmaps/valid/565-1x1.bmp | Bin 0 -> 70 bytes
.../data/bmp/bitmaps/valid/565-320x240-topdown.bmp | Bin 0 -> 153666 bytes
.../loaders/data/bmp/bitmaps/valid/565-320x240.bmp | Bin 0 -> 153666 bytes
.../data/bmp/bitmaps/valid/565-321x240-topdown.bmp | Bin 0 -> 154626 bytes
.../loaders/data/bmp/bitmaps/valid/565-321x240.bmp | Bin 0 -> 154626 bytes
.../data/bmp/bitmaps/valid/565-322x240-topdown.bmp | Bin 0 -> 154626 bytes
.../loaders/data/bmp/bitmaps/valid/565-322x240.bmp | Bin 0 -> 154626 bytes
tests/loaders/data/bmp/bitmaps/valid/8bpp-1x1.bmp | Bin 0 -> 82 bytes
.../data/bmp/bitmaps/valid/8bpp-1x64000.bmp | Bin 0 -> 256078 bytes
.../data/bmp/bitmaps/valid/8bpp-320x240.bmp | Bin 0 -> 76878 bytes
.../data/bmp/bitmaps/valid/8bpp-321x240.bmp | Bin 0 -> 77838 bytes
.../data/bmp/bitmaps/valid/8bpp-322x240.bmp | Bin 0 -> 77838 bytes
.../data/bmp/bitmaps/valid/8bpp-323x240.bmp | Bin 0 -> 77838 bytes
.../bmp/bitmaps/valid/8bpp-colorsimportant-two.bmp | Bin 0 -> 76878 bytes
.../bmp/bitmaps/valid/8bpp-colorsused-zero.bmp | Bin 0 -> 77878 bytes
.../bmp/bitmaps/valid/8bpp-topdown-320x240.bmp | Bin 0 -> 76878 bytes
tests/loaders/data/bmp/bitmaps/valid/index.html | 421 +++
.../bmp/bitmaps/valid/rle4-absolute-320x240.bmp | Bin 0 -> 40400 bytes
.../bmp/bitmaps/valid/rle4-alternate-320x240.bmp | Bin 0 -> 4142 bytes
.../data/bmp/bitmaps/valid/rle4-delta-320x240.bmp | Bin 0 -> 3686 bytes
.../bmp/bitmaps/valid/rle4-encoded-320x240.bmp | Bin 0 -> 4134 bytes
.../data/bmp/bitmaps/valid/rle8-64000x1.bmp | Bin 0 -> 586 bytes
.../bmp/bitmaps/valid/rle8-absolute-320x240.bmp | Bin 0 -> 78800 bytes
.../data/bmp/bitmaps/valid/rle8-blank-160x120.bmp | Bin 0 -> 1080 bytes
.../data/bmp/bitmaps/valid/rle8-delta-320x240.bmp | Bin 0 -> 4646 bytes
.../bmp/bitmaps/valid/rle8-encoded-320x240.bmp | Bin 0 -> 4134 bytes
tests/loaders/data/bmp/bmptestsuite.py | 3639 ++++++++++++++++++++
tests/loaders/loaders_suite.c | 93 +
150 files changed, 4801 insertions(+), 1 deletions(-)
create mode 100644 tests/loaders/data/bmp/README
create mode 100644 tests/loaders/data/bmp/bitmaps/corrupt/1bpp-no-palette.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/corrupt/1bpp-pixeldata-cropped.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/corrupt/24bpp-pixeldata-cropped.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/corrupt/32bpp-pixeldata-cropped.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/corrupt/4bpp-no-palette.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/corrupt/4bpp-pixeldata-cropped.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/corrupt/555-pixeldata-cropped.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/corrupt/8bpp-colorsimportant-large.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/corrupt/8bpp-colorsimportant-negative.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/corrupt/8bpp-colorsused-large.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/corrupt/8bpp-colorsused-negative.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/corrupt/8bpp-no-palette.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/corrupt/8bpp-pixeldata-cropped.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/corrupt/bitdepth-large.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/corrupt/bitdepth-odd.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/corrupt/bitdepth-zero.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/corrupt/colormasks-cropped.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/corrupt/colormasks-missing.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/corrupt/compression-bad-rle4-for-8bpp.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/corrupt/compression-bad-rle8-for-4bpp.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/corrupt/compression-unknown.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/corrupt/emptyfile.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/corrupt/fileinfoheader-cropped.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/corrupt/height-zero.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/corrupt/index.html
create mode 100644 tests/loaders/data/bmp/bitmaps/corrupt/infoheader-cropped.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/corrupt/infoheader-missing.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/corrupt/infoheadersize-large.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/corrupt/infoheadersize-small.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/corrupt/infoheadersize-zero.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/corrupt/magicnumber-bad.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/corrupt/magicnumber-cropped.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/corrupt/offbits-large.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/corrupt/offbits-negative.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/corrupt/offbits-zero.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/corrupt/palette-cropped.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/corrupt/palette-missing.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/corrupt/palette-too-big.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/corrupt/pixeldata-missing.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/corrupt/rle4-absolute-cropped.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/corrupt/rle4-delta-cropped.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/corrupt/rle4-no-end-of-line-marker.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/corrupt/rle4-runlength-cropped.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/corrupt/rle8-absolute-cropped.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/corrupt/rle8-delta-cropped.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/corrupt/rle8-deltaleavesimage.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/corrupt/rle8-no-end-of-line-marker.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/corrupt/rle8-runlength-cropped.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/corrupt/width-negative.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/corrupt/width-times-height-overflow.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/corrupt/width-zero.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/questionable/32bpp-0x0.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/questionable/32bpp-0x240.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/questionable/32bpp-320x0.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/questionable/8bpp-pixels-not-in-palette.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/questionable/filesize-bad.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/questionable/filesize-zero.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/questionable/index.html
create mode 100644 tests/loaders/data/bmp/bitmaps/questionable/pels-per-meter-x-large.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/questionable/pels-per-meter-x-negative.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/questionable/pels-per-meter-x-zero.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/questionable/pels-per-meter-y-large.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/questionable/pels-per-meter-y-negative.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/questionable/pels-per-meter-y-zero.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/questionable/pixeldata-rle8-toomuch.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/questionable/pixeldata-toomuch.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/questionable/planes-large.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/questionable/planes-zero.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/questionable/reserved1-bad.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/questionable/reserved2-bad.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/questionable/rle4-height-negative.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/questionable/rle4-no-end-of-bitmap-marker.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/questionable/rle8-height-negative.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/questionable/rle8-no-end-of-bitmap-marker.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/valid/1bpp-1x1.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/valid/1bpp-320x240-color.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/valid/1bpp-320x240-overlappingcolor.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/valid/1bpp-320x240.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/valid/1bpp-321x240.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/valid/1bpp-322x240.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/valid/1bpp-323x240.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/valid/1bpp-324x240.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/valid/1bpp-325x240.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/valid/1bpp-326x240.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/valid/1bpp-327x240.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/valid/1bpp-328x240.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/valid/1bpp-329x240.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/valid/1bpp-330x240.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/valid/1bpp-331x240.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/valid/1bpp-332x240.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/valid/1bpp-333x240.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/valid/1bpp-334x240.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/valid/1bpp-335x240.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/valid/1bpp-topdown-320x240.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/valid/24bpp-1x1.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/valid/24bpp-320x240.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/valid/24bpp-321x240.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/valid/24bpp-322x240.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/valid/24bpp-323x240.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/valid/24bpp-imagesize-zero.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/valid/24bpp-topdown-320x240.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/valid/32bpp-101110-320x240.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/valid/32bpp-1x1.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/valid/32bpp-320x240.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/valid/32bpp-888-optimalpalette-320x240.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/valid/32bpp-optimalpalette-320x240.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/valid/32bpp-topdown-320x240.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/valid/4bpp-1x1.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/valid/4bpp-320x240.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/valid/4bpp-321x240.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/valid/4bpp-322x240.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/valid/4bpp-323x240.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/valid/4bpp-324x240.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/valid/4bpp-325x240.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/valid/4bpp-326x240.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/valid/4bpp-327x240.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/valid/4bpp-topdown-320x240.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/valid/555-1x1.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/valid/555-320x240.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/valid/555-321x240.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/valid/565-1x1.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/valid/565-320x240-topdown.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/valid/565-320x240.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/valid/565-321x240-topdown.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/valid/565-321x240.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/valid/565-322x240-topdown.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/valid/565-322x240.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/valid/8bpp-1x1.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/valid/8bpp-1x64000.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/valid/8bpp-320x240.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/valid/8bpp-321x240.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/valid/8bpp-322x240.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/valid/8bpp-323x240.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/valid/8bpp-colorsimportant-two.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/valid/8bpp-colorsused-zero.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/valid/8bpp-topdown-320x240.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/valid/index.html
create mode 100644 tests/loaders/data/bmp/bitmaps/valid/rle4-absolute-320x240.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/valid/rle4-alternate-320x240.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/valid/rle4-delta-320x240.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/valid/rle4-encoded-320x240.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/valid/rle8-64000x1.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/valid/rle8-absolute-320x240.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/valid/rle8-blank-160x120.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/valid/rle8-delta-320x240.bmp
create mode 100644 tests/loaders/data/bmp/bitmaps/valid/rle8-encoded-320x240.bmp
create mode 100644 tests/loaders/data/bmp/bmptestsuite.py
repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos(a)gmail.com
if you want to unsubscribe, or site admin admin(a)repo.or.cz if you receive
no reply.
--
gfxprim.git ("A simple 2D graphics library with emphasis on correctness and well-defined operation.")
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project gfxprim.git.
The branch, master has been updated
via d20862dc07b9b8858ca929d9b91caa1eb6d88bbc (commit)
from 9ac2eb1478d0582c8e52b467aab9bf5a40a33fd2 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://repo.or.cz/w/gfxprim.git/commit/d20862dc07b9b8858ca929d9b91caa1eb6d8…
commit d20862dc07b9b8858ca929d9b91caa1eb6d88bbc
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sat Oct 13 18:23:39 2012 +0200
tests: core: Start core tests using new framework.
diff --git a/tests/core/Makefile b/tests/core/Makefile
index c848cb0..bafa3c2 100644
--- a/tests/core/Makefile
+++ b/tests/core/Makefile
@@ -2,14 +2,24 @@ TOPDIR=../..
include $(TOPDIR)/pre.mk
+#CSOURCES=$(shell echo *.c)
+
+# hack
LIBNAME=core
-TESTSUITE=core_suite
-LDLIBS+=-lGP -L$(TOPDIR)/build/ -lcheck -lm -lSDL
-GENSOURCES+=GP_Convert.test.gen.c GP_WritePixel.test.gen.c - GP_MixPixels.test.gen.c
-all: $(TESTSUITE)
+LDFLAGS+=-L../framework/ -L$(TOPDIR)/build/
+LDLIBS+=$(shell $(TOPDIR)/gfxprim-config --libs --libs-loaders)
+LDLIBS+=-ltst_preload -ldl -ltst
+CFLAGS+=-I../framework/
-include $(TOPDIR)/tests.mk
-include $(TOPDIR)/post.mk
+GENSOURCES+=WritePixel_testsuite.gen.c
+
+APPS=WritePixel_testsuite.gen
+$(APPS): ../framework/libtst.a
+
+CLEAN+=log.html log.json
+
+include $(TOPDIR)/gen.mk
+include $(TOPDIR)/app.mk
+include $(TOPDIR)/post.mk
diff --git a/tests/core/WritePixel_testsuite.gen.c.t b/tests/core/WritePixel_testsuite.gen.c.t
new file mode 100644
index 0000000..a554e9b
--- /dev/null
+++ b/tests/core/WritePixel_testsuite.gen.c.t
@@ -0,0 +1,122 @@
+/*****************************************************************************
+ * This file is part of gfxprim library. *
+ * *
+ * Gfxprim 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. *
+ * *
+ * Gfxprim 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. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with gfxprim; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
+ * Boston, MA 02110-1301 USA *
+ * *
+ * Copyright (C) 2009-2012 Cyril Hrubis <metan(a)ucw.cz> *
+ * *
+ *****************************************************************************/
+
+%% extends "base.test.c.t"
+
+%% block body
+
+#include <stdio.h>
+
+#include "GP_WritePixel.h"
+
+#include "tst_test.h"
+
+static void dump_buffer(const char *name, char *buf, unsigned int buf_len)
+{
+ unsigned int i;
+
+ printf("%s:n{", name);
+
+ for (i = 0; i < buf_len; i++) {
+ printf("%i", !!buf[i]);
+
+ if (i != buf_len - 1)
+ printf(", ");
+
+ if (i % 26 == 25)
+ printf("n ");
+ }
+
+ printf("}n");
+}
+
+/*
+ * Compares two statically defined buffers
+ */
+#define COMPARE_BUFFERS(id, buf1, buf2) do { + unsigned int buf1_len = sizeof(buf1)/sizeof(*buf1); + unsigned int buf2_len = sizeof(buf2)/sizeof(*buf2); + unsigned int i; + + if (buf1_len != buf2_len) { + tst_report(0, "Invalid buffers"); + return TST_FAILED; + } + + for (i = 0; i < buf1_len; i++) + if(buf1[i] != buf2[i]) { + printf("%sn", id); + dump_buffer("wrote", buf1, buf1_len); + dump_buffer("gen", buf2, buf2_len); + tst_report(0, "Buffers are different"); + return TST_FAILED; + } + + return
TST_SUCCESS; +} while (0)
+
+%% for pixelsize in [8, 16, 24, 32]
+%% for offset in range(0, 4)
+%% for len in range(0, 6)
+%% for aligment in [0, 1]
+static int WritePixel{{ "_%i_%i_%i_%i"|format(pixelsize, offset, len, aligment) }}(void)
+//, {{ ""offset=%i, len=%i, aligment=%i,""|format(offset, len, aligment) }})
+{
+ char write_buf[{{ 25 * pixelsize//8 }}] = {};
+ char gen_buf[{{ 25 * pixelsize//8 }}] = {};
+
+ /*
+ * Fill the compare buffer
+ */
+%% for i in range(0, len)
+%% for j in range(0, pixelsize//8)
+ gen_buf[{{aligment + offset * pixelsize//8 + i * pixelsize//8 + j}}] = 0xff;
+%% endfor
+%% endfor
+
+ GP_WritePixels{{ pixelsize }}bpp(write_buf + {{aligment + offset * pixelsize//8}}, {{ len }}, 0xffffffff>>{{32 - pixelsize}});
+
+ COMPARE_BUFFERS({{""p=%i o=%i l=%i a=%i""|format(pixelsize, offset, len, aligment)}}, write_buf, gen_buf);
+}
+%% endfor
+%% endfor
+%% endfor
+%% endfor
+
+const struct tst_suite tst_suite = {
+ .suite_name = "WritePixel Testsuite",
+ .tests = {
+%% for pixelsize in [8, 16, 24, 32]
+%% for offset in range(0, 4)
+%% for len in range(0, 6)
+%% for aligment in [0, 1]
+ {.name = "WritePixel {{ pixelsize }} {{ offset }} {{ len }} {{ aligment }}",
+ .tst_fn = WritePixel{{ "_%i_%i_%i_%i"|format(pixelsize, offset, len, aligment) }}},
+%% endfor
+%% endfor
+%% endfor
+%% endfor
+ {.name = NULL}
+ }
+};
+
+%% endblock body
diff --git a/tests/core/runtest.sh b/tests/core/runtest.sh
new file mode 100755
index 0000000..0a9821e
--- /dev/null
+++ b/tests/core/runtest.sh
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+#
+# By default the glibc __libc_message() writes to /dev/tty before calling
+# the abort(). Exporting this macro makes it to use stderr instead.
+#
+# The main usage of the function are malloc assertions, so this makes us catch
+# the malloc error message by catching stderr output.
+#
+export LIBC_FATAL_STDERR_=1
+
+LD_PRELOAD=`pwd`/../framework/libtst_preload.so LD_LIBRARY_PATH=../../build/ ./WritePixel_testsuite.gen "$@"
diff --git a/tests/core/GP_Blit.test.c b/tests/core_old/GP_Blit.test.c
similarity index 100%
rename from tests/core/GP_Blit.test.c
rename to tests/core_old/GP_Blit.test.c
diff --git a/tests/core/GP_Common.test.c b/tests/core_old/GP_Common.test.c
similarity index 100%
rename from tests/core/GP_Common.test.c
rename to tests/core_old/GP_Common.test.c
diff --git a/tests/core/GP_Convert.test.c b/tests/core_old/GP_Convert.test.c
similarity index 100%
rename from tests/core/GP_Convert.test.c
rename to tests/core_old/GP_Convert.test.c
diff --git a/tests/core/GP_Convert.test.gen.c.t b/tests/core_old/GP_Convert.test.gen.c.t
similarity index 100%
rename from tests/core/GP_Convert.test.gen.c.t
rename to tests/core_old/GP_Convert.test.gen.c.t
diff --git a/tests/core/GP_Counter.test.c b/tests/core_old/GP_Counter.test.c
similarity index 100%
rename from tests/core/GP_Counter.test.c
rename to tests/core_old/GP_Counter.test.c
diff --git a/tests/core/GP_MixPixels.test.gen.c.t b/tests/core_old/GP_MixPixels.test.gen.c.t
similarity index 100%
rename from tests/core/GP_MixPixels.test.gen.c.t
rename to tests/core_old/GP_MixPixels.test.gen.c.t
diff --git a/tests/core/GP_WritePixel.test.gen.c.t b/tests/core_old/GP_WritePixel.test.gen.c.t
similarity index 100%
rename from tests/core/GP_WritePixel.test.gen.c.t
rename to tests/core_old/GP_WritePixel.test.gen.c.t
diff --git a/tests/core/Makefile b/tests/core_old/Makefile
similarity index 100%
copy from tests/core/Makefile
copy to tests/core_old/Makefile
-----------------------------------------------------------------------
Summary of changes:
tests/core/Makefile | 24 +++-
tests/core/WritePixel_testsuite.gen.c.t | 122 ++++++++++++++++++++
tests/{loaders => core}/runtest.sh | 2 +-
tests/{core => core_old}/GP_Blit.test.c | 0
tests/{core => core_old}/GP_Common.test.c | 0
tests/{core => core_old}/GP_Convert.test.c | 0
tests/{core => core_old}/GP_Convert.test.gen.c.t | 0
tests/{core => core_old}/GP_Counter.test.c | 0
tests/{core => core_old}/GP_MixPixels.test.gen.c.t | 0
.../{core => core_old}/GP_WritePixel.test.gen.c.t | 0
tests/{core => core_old}/Makefile | 0
11 files changed, 140 insertions(+), 8 deletions(-)
create mode 100644 tests/core/WritePixel_testsuite.gen.c.t
copy tests/{loaders => core}/runtest.sh (89%)
rename tests/{core => core_old}/GP_Blit.test.c (100%)
rename tests/{core => core_old}/GP_Common.test.c (100%)
rename tests/{core => core_old}/GP_Convert.test.c (100%)
rename tests/{core => core_old}/GP_Convert.test.gen.c.t (100%)
rename tests/{core => core_old}/GP_Counter.test.c (100%)
rename tests/{core => core_old}/GP_MixPixels.test.gen.c.t (100%)
rename tests/{core => core_old}/GP_WritePixel.test.gen.c.t (100%)
copy tests/{core => core_old}/Makefile (100%)
repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos(a)gmail.com
if you want to unsubscribe, or site admin admin(a)repo.or.cz if you receive
no reply.
--
gfxprim.git ("A simple 2D graphics library with emphasis on correctness and well-defined operation.")
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project gfxprim.git.
The branch, master has been updated
via 9ac2eb1478d0582c8e52b467aab9bf5a40a33fd2 (commit)
from 727d637ad22f615be1b18741e3efd9a829dfed2b (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://repo.or.cz/w/gfxprim.git/commit/9ac2eb1478d0582c8e52b467aab9bf5a40a3…
commit 9ac2eb1478d0582c8e52b467aab9bf5a40a33fd2
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sat Oct 13 17:52:26 2012 +0200
tests: framework: Fix stupid typo.
diff --git a/tests/framework/tst_job.c b/tests/framework/tst_job.c
index ad71ba8..a1f7272 100644
--- a/tests/framework/tst_job.c
+++ b/tests/framework/tst_job.c
@@ -333,7 +333,7 @@ static int tst_job_benchmark(struct tst_job *job)
/* Send data to parent */
write_timespec(job, 'M', &sum);
- write_timespec(job, 'D', &dev);
+ write_timespec(job, 'V', &dev);
return TST_SUCCESS;
}
@@ -522,7 +522,7 @@ void tst_job_wait(struct tst_job *job)
sizeof(job->malloc_stats));
break;
default:
- //TODO: internal error
+ tst_warn("parent: Invalid characters received");
break;
}
}
-----------------------------------------------------------------------
Summary of changes:
tests/framework/tst_job.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos(a)gmail.com
if you want to unsubscribe, or site admin admin(a)repo.or.cz if you receive
no reply.
--
gfxprim.git ("A simple 2D graphics library with emphasis on correctness and well-defined operation.")