hcs, ts, gdi3

This commit is contained in:
Ulf Gebhardt 2011-10-18 11:14:08 +02:00
parent 360cf175a1
commit e1d2b1a5ab
55 changed files with 3030 additions and 0 deletions

BIN
ss2011/hcs/1c_henrich.txt Normal file

Binary file not shown.

30
ss2011/hcs/hcs.txt Normal file
View File

@ -0,0 +1,30 @@
78 54 96 0
01001110 00110110 01100|000 00000000
01001110 00110110 01100|111 11111111
78 54 103 255
78 54 120 0
01001110 00110110 01111|000 00000000
01001110 00110110 01111|111 11111111
78 54 127 255
01001110 00110110 011|00000 00000000
01001110 00110110 011|11111 11111111
31 19 0 0 -> No1
00011111 00010011 0000000|00 00000000
31 19 59 255 -> NO1
00011111 00010011 0001110|11 11111111
31 19 60 0 -> No2
00011111 00010011 0001111|00 00000000
31 19 63 255 -> No2
00011111 00010011 0001111|11 11111111
31 19 64 0 -> NO1
00011111 00010011 0010000|00 00000000
31 19 127 255 -> NO1
00011111 00010011 0011111|11 11111111

25
ss2011/hcs/hcs_1b.txt Normal file
View File

@ -0,0 +1,25 @@
Ulf Gebhardt 1574373
Frage: Erklären Sie die Begriffe Chromaticity und Spektralfarblinie.
Antwort:
Chromaticity:
Die Farbsättigung (Chromaticity), Sättigung ist neben Farbton und Helligkeit
eine der drei vom Menschen als grundlegend empfundenen Eigenschaften einer Farbe.
Sie beschreibt die Qualität der Farbwirkung. Spezielle Wertigkeiten wie Buntheit,
Farbigkeit (Farbintensität), Chromatizität, Farbtiefe, Brillanz, Graustich beschreiben
verwandte Phänomene für bunte und unbunte Farben.
Spektralfarblinie:
Die Spektralfarblinie ist Begrenzung der Farbsättigung, wenn man sie zweidimensional
aufträgt. Formal: Die x,y Kordinaten der monochromatischen Farbreize erzeuegn die
Spektralfarblinie. Sie bildet die konvexe Hülle der Farbsättigungskoordinaten der
Farbreize
Sry für die Verspätung ;-)

View File

@ -0,0 +1,323 @@
/* Simple program: Move N sprites around on the screen as fast as possible */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
#include <time.h>
#include "SDL.h"
#define NUM_SPRITES 100
#define MAX_SPEED 1
SDL_Surface *sprite;
int numsprites;
SDL_Rect *sprite_rects;
SDL_Rect *positions;
SDL_Rect *velocities;
int sprites_visible;
int debug_flip;
Uint16 sprite_w, sprite_h;
/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
static void quit(int rc)
{
SDL_Quit();
exit(rc);
}
int LoadSprite(char *file)
{
SDL_Surface *temp;
/* Load the sprite image */
sprite = SDL_LoadBMP(file);
if ( sprite == NULL ) {
fprintf(stderr, "Couldn't load %s: %s", file, SDL_GetError());
return(-1);
}
/* Set transparent pixel as the pixel at (0,0) */
if ( sprite->format->palette ) {
SDL_SetColorKey(sprite, (SDL_SRCCOLORKEY|SDL_RLEACCEL),
*(Uint8 *)sprite->pixels);
}
/* Convert sprite to video format */
temp = SDL_DisplayFormat(sprite);
SDL_FreeSurface(sprite);
if ( temp == NULL ) {
fprintf(stderr, "Couldn't convert background: %s\n",
SDL_GetError());
return(-1);
}
sprite = temp;
/* We're ready to roll. :) */
return(0);
}
void MoveSprites(SDL_Surface *screen, Uint32 background)
{
int i, nupdates;
SDL_Rect area, *position, *velocity;
nupdates = 0;
/* Erase all the sprites if necessary */
if ( sprites_visible ) {
SDL_FillRect(screen, NULL, background);
}
/* Move the sprite, bounce at the wall, and draw */
for ( i=0; i<numsprites; ++i ) {
position = &positions[i];
velocity = &velocities[i];
position->x += velocity->x;
if ( (position->x < 0) || (position->x >= (screen->w - sprite_w)) ) {
velocity->x = -velocity->x;
position->x += velocity->x;
}
position->y += velocity->y;
if ( (position->y < 0) || (position->y >= (screen->h - sprite_w)) ) {
velocity->y = -velocity->y;
position->y += velocity->y;
}
/* Blit the sprite onto the screen */
area = *position;
SDL_BlitSurface(sprite, NULL, screen, &area);
sprite_rects[nupdates++] = area;
}
if (debug_flip) {
if ( (screen->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF ) {
static int t = 0;
Uint32 color = SDL_MapRGB (screen->format, 255, 0, 0);
SDL_Rect r;
r.x = (sin((float)t * 2 * 3.1459) + 1.0) / 2.0 * (screen->w-20);
r.y = 0;
r.w = 20;
r.h = screen->h;
SDL_FillRect (screen, &r, color);
t+=2;
}
}
/* Update the screen! */
if ( (screen->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF ) {
SDL_Flip(screen);
} else {
SDL_UpdateRects(screen, nupdates, sprite_rects);
}
sprites_visible = 1;
}
/* This is a way of telling whether or not to use hardware surfaces */
Uint32 FastestFlags(Uint32 flags, int width, int height, int bpp)
{
const SDL_VideoInfo *info;
/* Hardware acceleration is only used in fullscreen mode */
flags |= SDL_FULLSCREEN;
/* Check for various video capabilities */
info = SDL_GetVideoInfo();
if ( info->blit_hw_CC && info->blit_fill ) {
/* We use accelerated colorkeying and color filling */
flags |= SDL_HWSURFACE;
}
/* If we have enough video memory, and will use accelerated
blits directly to it, then use page flipping.
*/
if ( (flags & SDL_HWSURFACE) == SDL_HWSURFACE ) {
/* Direct hardware blitting without double-buffering
causes really bad flickering.
*/
if ( info->video_mem*1024 > (height*width*bpp/8) ) {
flags |= SDL_DOUBLEBUF;
} else {
flags &= ~SDL_HWSURFACE;
}
}
/* Return the flags */
return(flags);
}
int main(int argc, char *argv[])
{
SDL_Surface *screen;
Uint8 *mem;
int width, height;
Uint8 video_bpp;
Uint32 videoflags;
Uint32 background;
int i, done;
SDL_Event event;
Uint32 then, now, frames;
/* Initialize SDL */
if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError());
return(1);
}
numsprites = NUM_SPRITES;
videoflags = SDL_SWSURFACE|SDL_ANYFORMAT;
width = 640;
height = 480;
video_bpp = 8;
debug_flip = 0;
while ( argc > 1 ) {
--argc;
if ( strcmp(argv[argc-1], "-width") == 0 ) {
width = atoi(argv[argc]);
--argc;
} else
if ( strcmp(argv[argc-1], "-height") == 0 ) {
height = atoi(argv[argc]);
--argc;
} else
if ( strcmp(argv[argc-1], "-bpp") == 0 ) {
video_bpp = atoi(argv[argc]);
videoflags &= ~SDL_ANYFORMAT;
--argc;
} else
if ( strcmp(argv[argc], "-fast") == 0 ) {
videoflags = FastestFlags(videoflags, width, height, video_bpp);
} else
if ( strcmp(argv[argc], "-hw") == 0 ) {
videoflags ^= SDL_HWSURFACE;
} else
if ( strcmp(argv[argc], "-flip") == 0 ) {
videoflags ^= SDL_DOUBLEBUF;
} else
if ( strcmp(argv[argc], "-debugflip") == 0 ) {
debug_flip ^= 1;
} else
if ( strcmp(argv[argc], "-fullscreen") == 0 ) {
videoflags ^= SDL_FULLSCREEN;
} else
if ( isdigit(argv[argc][0]) ) {
numsprites = atoi(argv[argc]);
} else {
fprintf(stderr,
"Usage: %s [-bpp N] [-hw] [-flip] [-fast] [-fullscreen] [numsprites]\n",
argv[0]);
quit(1);
}
}
/* Set video mode */
screen = SDL_SetVideoMode(width, height, video_bpp, videoflags);
if ( ! screen ) {
fprintf(stderr, "Couldn't set %dx%d video mode: %s\n",
width, height, SDL_GetError());
quit(2);
}
/* Load the sprite */
if ( LoadSprite("icon.bmp") < 0 ) {
quit(1);
}
/* Allocate memory for the sprite info */
mem = (Uint8 *)malloc(4*sizeof(SDL_Rect)*numsprites);
if ( mem == NULL ) {
SDL_FreeSurface(sprite);
fprintf(stderr, "Out of memory!\n");
quit(2);
}
sprite_rects = (SDL_Rect *)mem;
positions = sprite_rects;
sprite_rects += numsprites;
velocities = sprite_rects;
sprite_rects += numsprites;
sprite_w = sprite->w;
sprite_h = sprite->h;
srand(time(NULL));
for ( i=0; i<numsprites; ++i ) {
positions[i].x = rand()%(screen->w - sprite_w);
positions[i].y = rand()%(screen->h - sprite_h);
positions[i].w = sprite->w;
positions[i].h = sprite->h;
velocities[i].x = 0;
velocities[i].y = 0;
while ( ! velocities[i].x && ! velocities[i].y ) {
velocities[i].x = (rand()%(MAX_SPEED*2+1))-MAX_SPEED;
velocities[i].y = (rand()%(MAX_SPEED*2+1))-MAX_SPEED;
}
}
background = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
/* Print out information about our surfaces */
printf("Screen is at %d bits per pixel\n",screen->format->BitsPerPixel);
if ( (screen->flags & SDL_HWSURFACE) == SDL_HWSURFACE ) {
printf("Screen is in video memory\n");
} else {
printf("Screen is in system memory\n");
}
if ( (screen->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF ) {
printf("Screen has double-buffering enabled\n");
}
if ( (sprite->flags & SDL_HWSURFACE) == SDL_HWSURFACE ) {
printf("Sprite is in video memory\n");
} else {
printf("Sprite is in system memory\n");
}
/* Run a sample blit to trigger blit acceleration */
{ SDL_Rect dst;
dst.x = 0;
dst.y = 0;
dst.w = sprite->w;
dst.h = sprite->h;
SDL_BlitSurface(sprite, NULL, screen, &dst);
SDL_FillRect(screen, &dst, background);
}
if ( (sprite->flags & SDL_HWACCEL) == SDL_HWACCEL ) {
printf("Sprite blit uses hardware acceleration\n");
}
if ( (sprite->flags & SDL_RLEACCEL) == SDL_RLEACCEL ) {
printf("Sprite blit uses RLE acceleration\n");
}
/* Loop, blitting sprites and waiting for a keystroke */
frames = 0;
then = SDL_GetTicks();
done = 0;
sprites_visible = 0;
while ( !done ) {
/* Check for events */
++frames;
while ( SDL_PollEvent(&event) ) {
switch (event.type) {
case SDL_MOUSEBUTTONDOWN:
SDL_WarpMouse(screen->w/2, screen->h/2);
break;
case SDL_KEYDOWN:
/* Any keypress quits the app... */
case SDL_QUIT:
done = 1;
break;
default:
break;
}
}
MoveSprites(screen, background);
}
SDL_FreeSurface(sprite);
free(mem);
/* Print out some timing information */
now = SDL_GetTicks();
if ( now > then ) {
printf("%2.2f frames per second\n",
((double)frames*1000)/(now-then));
}
SDL_Quit();
return(0);
}

View File

@ -0,0 +1,87 @@
/* Test program to check the resolution of the SDL timer on the current
platform
*/
#include <stdlib.h>
#include <stdio.h>
#include "SDL.h"
#define DEFAULT_RESOLUTION 1
static int ticks = 0;
static Uint32 SDLCALL ticktock(Uint32 interval)
{
++ticks;
return(interval);
}
static Uint32 SDLCALL callback(Uint32 interval, void *param)
{
printf("Timer %d : param = %d\n", interval, (int)(uintptr_t)param);
return interval;
}
int main(int argc, char *argv[])
{
int desired;
SDL_TimerID t1, t2, t3;
if ( SDL_Init(SDL_INIT_TIMER) < 0 ) {
fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError());
return(1);
}
/* Start the timer */
desired = 0;
if ( argv[1] ) {
desired = atoi(argv[1]);
}
if ( desired == 0 ) {
desired = DEFAULT_RESOLUTION;
}
SDL_SetTimer(desired, ticktock);
/* Wait 10 seconds */
printf("Waiting 10 seconds\n");
SDL_Delay(10*1000);
/* Stop the timer */
SDL_SetTimer(0, NULL);
/* Print the results */
if ( ticks ) {
fprintf(stderr,
"Timer resolution: desired = %d ms, actual = %f ms\n",
desired, (double)(10*1000)/ticks);
}
/* Test multiple timers */
printf("Testing multiple timers...\n");
t1 = SDL_AddTimer(100, callback, (void*)1);
if(!t1)
fprintf(stderr,"Could not create timer 1: %s\n", SDL_GetError());
t2 = SDL_AddTimer(50, callback, (void*)2);
if(!t2)
fprintf(stderr,"Could not create timer 2: %s\n", SDL_GetError());
t3 = SDL_AddTimer(233, callback, (void*)3);
if(!t3)
fprintf(stderr,"Could not create timer 3: %s\n", SDL_GetError());
/* Wait 10 seconds */
printf("Waiting 10 seconds\n");
SDL_Delay(10*1000);
printf("Removing timer 1 and waiting 5 more seconds\n");
SDL_RemoveTimer(t1);
SDL_Delay(5*1000);
SDL_RemoveTimer(t2);
SDL_RemoveTimer(t3);
SDL_Quit();
return(0);
}

View File

@ -0,0 +1,37 @@
/* Test program to compare the compile-time version of SDL with the linked
version of SDL
*/
#include <stdio.h>
#include <stdlib.h>
#include "SDL.h"
int main(int argc, char *argv[])
{
SDL_version compiled;
/* Initialize SDL */
if ( SDL_Init(0) < 0 ) {
fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError());
exit(1);
}
#ifdef DEBUG
fprintf(stderr, "SDL initialized\n");
#endif
#if SDL_VERSION_ATLEAST(1, 2, 0)
printf("Compiled with SDL 1.2 or newer\n");
#else
printf("Compiled with SDL older than 1.2\n");
#endif
SDL_VERSION(&compiled);
printf("Compiled version: %d.%d.%d\n",
compiled.major, compiled.minor, compiled.patch);
printf("Linked version: %d.%d.%d\n",
SDL_Linked_Version()->major,
SDL_Linked_Version()->minor,
SDL_Linked_Version()->patch);
SDL_Quit();
return(0);
}

View File

@ -0,0 +1,465 @@
/* Simple program -- figure out what kind of video display we have */
#include <stdlib.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "SDL.h"
#define NUM_BLITS 10
#define NUM_UPDATES 500
#define FLAG_MASK (SDL_HWSURFACE | SDL_FULLSCREEN | SDL_DOUBLEBUF | \
SDL_SRCCOLORKEY | SDL_SRCALPHA | SDL_RLEACCEL | \
SDL_RLEACCELOK)
void PrintFlags(Uint32 flags)
{
printf("0x%8.8x", (flags & FLAG_MASK));
if ( flags & SDL_HWSURFACE ) {
printf(" SDL_HWSURFACE");
} else {
printf(" SDL_SWSURFACE");
}
if ( flags & SDL_FULLSCREEN ) {
printf(" | SDL_FULLSCREEN");
}
if ( flags & SDL_DOUBLEBUF ) {
printf(" | SDL_DOUBLEBUF");
}
if ( flags & SDL_SRCCOLORKEY ) {
printf(" | SDL_SRCCOLORKEY");
}
if ( flags & SDL_SRCALPHA ) {
printf(" | SDL_SRCALPHA");
}
if ( flags & SDL_RLEACCEL ) {
printf(" | SDL_RLEACCEL");
}
if ( flags & SDL_RLEACCELOK ) {
printf(" | SDL_RLEACCELOK");
}
}
int RunBlitTests(SDL_Surface *screen, SDL_Surface *bmp, int blitcount)
{
int i, j;
int maxx;
int maxy;
SDL_Rect dst;
maxx = (int)screen->w - bmp->w + 1;
maxy = (int)screen->h - bmp->h + 1;
for ( i = 0; i < NUM_UPDATES; ++i ) {
for ( j = 0; j < blitcount; ++j ) {
if ( maxx ) {
dst.x = rand() % maxx;
} else {
dst.x = 0;
}
if ( maxy ) {
dst.y = rand() % maxy;
} else {
dst.y = 0;
}
dst.w = bmp->w;
dst.h = bmp->h;
SDL_BlitSurface(bmp, NULL, screen, &dst);
}
SDL_Flip(screen);
}
return i;
}
int RunModeTests(SDL_Surface *screen)
{
Uint32 then, now;
Uint32 frames;
float seconds;
int i;
Uint8 r, g, b;
SDL_Surface *bmp, *bmpcc, *tmp;
SDL_Event event;
while ( SDL_PollEvent(&event) ) {
if ( event.type == SDL_KEYDOWN )
return 0;
}
/* First test fills and screen update speed */
printf("Running color fill and fullscreen update test\n");
then = SDL_GetTicks();
frames = 0;
for ( i = 0; i < 256; ++i ) {
r = i;
g = 0;
b = 0;
SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, r, g, b));
SDL_Flip(screen);
++frames;
}
for ( i = 0; i < 256; ++i ) {
r = 0;
g = i;
b = 0;
SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, r, g, b));
SDL_Flip(screen);
++frames;
}
for ( i = 0; i < 256; ++i ) {
r = 0;
g = 0;
b = i;
SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, r, g, b));
SDL_Flip(screen);
++frames;
}
now = SDL_GetTicks();
seconds = (float)(now - then) / 1000.0f;
if ( seconds > 0.0f ) {
printf("%d fills and flips in %2.2f seconds, %2.2f FPS\n", frames, seconds, (float)frames / seconds);
} else {
printf("%d fills and flips in zero seconds!n", frames);
}
/* clear the screen after fill test */
SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0));
SDL_Flip(screen);
while ( SDL_PollEvent(&event) ) {
if ( event.type == SDL_KEYDOWN )
return 0;
}
/* run the generic blit test */
bmp = SDL_LoadBMP("sample.bmp");
if ( ! bmp ) {
printf("Couldn't load sample.bmp: %s\n", SDL_GetError());
return 0;
}
printf("Running freshly loaded blit test: %dx%d at %d bpp, flags: ",
bmp->w, bmp->h, bmp->format->BitsPerPixel);
PrintFlags(bmp->flags);
printf("\n");
then = SDL_GetTicks();
frames = RunBlitTests(screen, bmp, NUM_BLITS);
now = SDL_GetTicks();
seconds = (float)(now - then) / 1000.0f;
if ( seconds > 0.0f ) {
printf("%d blits / %d updates in %2.2f seconds, %2.2f FPS\n", NUM_BLITS*frames, frames, seconds, (float)frames / seconds);
} else {
printf("%d blits / %d updates in zero seconds!\n", NUM_BLITS*frames, frames);
}
/* clear the screen after blit test */
SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0));
SDL_Flip(screen);
while ( SDL_PollEvent(&event) ) {
if ( event.type == SDL_KEYDOWN )
return 0;
}
/* run the colorkeyed blit test */
bmpcc = SDL_LoadBMP("sample.bmp");
if ( ! bmpcc ) {
printf("Couldn't load sample.bmp: %s\n", SDL_GetError());
return 0;
}
printf("Running freshly loaded cc blit test: %dx%d at %d bpp, flags: ",
bmpcc->w, bmpcc->h, bmpcc->format->BitsPerPixel);
SDL_SetColorKey(bmpcc, SDL_SRCCOLORKEY | SDL_RLEACCEL, *(Uint8 *)bmpcc->pixels);
PrintFlags(bmpcc->flags);
printf("\n");
then = SDL_GetTicks();
frames = RunBlitTests(screen, bmpcc, NUM_BLITS);
now = SDL_GetTicks();
seconds = (float)(now - then) / 1000.0f;
if ( seconds > 0.0f ) {
printf("%d cc blits / %d updates in %2.2f seconds, %2.2f FPS\n", NUM_BLITS*frames, frames, seconds, (float)frames / seconds);
} else {
printf("%d cc blits / %d updates in zero seconds!\n", NUM_BLITS*frames, frames);
}
/* clear the screen after cc blit test */
SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0));
SDL_Flip(screen);
while ( SDL_PollEvent(&event) ) {
if ( event.type == SDL_KEYDOWN )
return 0;
}
/* run the generic blit test */
tmp = bmp;
bmp = SDL_DisplayFormat(bmp);
SDL_FreeSurface(tmp);
if ( ! bmp ) {
printf("Couldn't convert sample.bmp: %s\n", SDL_GetError());
return 0;
}
printf("Running display format blit test: %dx%d at %d bpp, flags: ",
bmp->w, bmp->h, bmp->format->BitsPerPixel);
PrintFlags(bmp->flags);
printf("\n");
then = SDL_GetTicks();
frames = RunBlitTests(screen, bmp, NUM_BLITS);
now = SDL_GetTicks();
seconds = (float)(now - then) / 1000.0f;
if ( seconds > 0.0f ) {
printf("%d blits / %d updates in %2.2f seconds, %2.2f FPS\n", NUM_BLITS*frames, frames, seconds, (float)frames / seconds);
} else {
printf("%d blits / %d updates in zero seconds!\n", NUM_BLITS*frames, frames);
}
/* clear the screen after blit test */
SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0));
SDL_Flip(screen);
while ( SDL_PollEvent(&event) ) {
if ( event.type == SDL_KEYDOWN )
return 0;
}
/* run the colorkeyed blit test */
tmp = bmpcc;
bmpcc = SDL_DisplayFormat(bmpcc);
SDL_FreeSurface(tmp);
if ( ! bmpcc ) {
printf("Couldn't convert sample.bmp: %s\n", SDL_GetError());
return 0;
}
printf("Running display format cc blit test: %dx%d at %d bpp, flags: ",
bmpcc->w, bmpcc->h, bmpcc->format->BitsPerPixel);
PrintFlags(bmpcc->flags);
printf("\n");
then = SDL_GetTicks();
frames = RunBlitTests(screen, bmpcc, NUM_BLITS);
now = SDL_GetTicks();
seconds = (float)(now - then) / 1000.0f;
if ( seconds > 0.0f ) {
printf("%d cc blits / %d updates in %2.2f seconds, %2.2f FPS\n", NUM_BLITS*frames, frames, seconds, (float)frames / seconds);
} else {
printf("%d cc blits / %d updates in zero seconds!\n", NUM_BLITS*frames, frames);
}
/* clear the screen after cc blit test */
SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0));
SDL_Flip(screen);
while ( SDL_PollEvent(&event) ) {
if ( event.type == SDL_KEYDOWN )
return 0;
}
/* run the alpha blit test only if screen bpp>8 */
if (bmp->format->BitsPerPixel>8)
{
SDL_FreeSurface(bmp);
bmp = SDL_LoadBMP("sample.bmp");
SDL_SetAlpha(bmp, SDL_SRCALPHA, 85); /* 85 - 33% alpha */
tmp = bmp;
bmp = SDL_DisplayFormat(bmp);
SDL_FreeSurface(tmp);
if ( ! bmp ) {
printf("Couldn't convert sample.bmp: %s\n", SDL_GetError());
return 0;
}
printf("Running display format alpha blit test: %dx%d at %d bpp, flags: ",
bmp->w, bmp->h, bmp->format->BitsPerPixel);
PrintFlags(bmp->flags);
printf("\n");
then = SDL_GetTicks();
frames = RunBlitTests(screen, bmp, NUM_BLITS);
now = SDL_GetTicks();
seconds = (float)(now - then) / 1000.0f;
if ( seconds > 0.0f ) {
printf("%d alpha blits / %d updates in %2.2f seconds, %2.2f FPS\n", NUM_BLITS*frames, frames, seconds, (float)frames / seconds);
} else {
printf("%d alpha blits / %d updates in zero seconds!\n", NUM_BLITS*frames, frames);
}
}
/* clear the screen after alpha blit test */
SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0));
SDL_Flip(screen);
while ( SDL_PollEvent(&event) ) {
if ( event.type == SDL_KEYDOWN )
return 0;
}
/* run the cc+alpha blit test only if screen bpp>8 */
if (bmp->format->BitsPerPixel>8)
{
SDL_FreeSurface(bmpcc);
bmpcc = SDL_LoadBMP("sample.bmp");
SDL_SetAlpha(bmpcc, SDL_SRCALPHA, 85); /* 85 - 33% alpha */
SDL_SetColorKey(bmpcc, SDL_SRCCOLORKEY | SDL_RLEACCEL, *(Uint8 *)bmpcc->pixels);
tmp = bmpcc;
bmpcc = SDL_DisplayFormat(bmpcc);
SDL_FreeSurface(tmp);
if ( ! bmpcc ) {
printf("Couldn't convert sample.bmp: %s\n", SDL_GetError());
return 0;
}
printf("Running display format cc+alpha blit test: %dx%d at %d bpp, flags: ",
bmpcc->w, bmpcc->h, bmpcc->format->BitsPerPixel);
PrintFlags(bmpcc->flags);
printf("\n");
then = SDL_GetTicks();
frames = RunBlitTests(screen, bmpcc, NUM_BLITS);
now = SDL_GetTicks();
seconds = (float)(now - then) / 1000.0f;
if ( seconds > 0.0f ) {
printf("%d cc+alpha blits / %d updates in %2.2f seconds, %2.2f FPS\n", NUM_BLITS*frames, frames, seconds, (float)frames / seconds);
} else {
printf("%d cc+alpha blits / %d updates in zero seconds!\n", NUM_BLITS*frames, frames);
}
}
SDL_FreeSurface(bmpcc);
SDL_FreeSurface(bmp);
while ( SDL_PollEvent(&event) ) {
if ( event.type == SDL_KEYDOWN )
return 0;
}
return 1;
}
void RunVideoTests()
{
static const struct {
int w, h, bpp;
} mode_list[] = {
{ 640, 480, 8 }, { 640, 480, 16 }, { 640, 480, 32 },
{ 800, 600, 8 }, { 800, 600, 16 }, { 800, 600, 32 },
{ 1024, 768, 8 }, { 1024, 768, 16 }, { 1024, 768, 32 }
};
static const Uint32 flags[] = {
(SDL_SWSURFACE),
(SDL_SWSURFACE | SDL_FULLSCREEN),
(SDL_HWSURFACE | SDL_FULLSCREEN),
(SDL_HWSURFACE | SDL_FULLSCREEN | SDL_DOUBLEBUF)
};
int i, j;
SDL_Surface *screen;
/* Test out several different video mode combinations */
SDL_WM_SetCaption("SDL Video Benchmark", "vidtest");
SDL_ShowCursor(0);
for ( i = 0; i < SDL_TABLESIZE(mode_list); ++i ) {
for ( j = 0; j < SDL_TABLESIZE(flags); ++j ) {
printf("===================================\n");
printf("Setting video mode: %dx%d at %d bpp, flags: ",
mode_list[i].w,
mode_list[i].h,
mode_list[i].bpp);
PrintFlags(flags[j]);
printf("\n");
screen = SDL_SetVideoMode(mode_list[i].w,
mode_list[i].h,
mode_list[i].bpp,
flags[j]);
if ( ! screen ) {
printf("Setting video mode failed: %s\n", SDL_GetError());
continue;
}
if ( (screen->flags & FLAG_MASK) != flags[j] ) {
printf("Flags didn't match: ");
PrintFlags(screen->flags);
printf("\n");
continue;
}
if ( ! RunModeTests(screen) ) {
return;
}
}
}
}
int main(int argc, char *argv[])
{
const SDL_VideoInfo *info;
int i;
SDL_Rect **modes;
char driver[128];
if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
fprintf(stderr,
"Couldn't initialize SDL: %s\n", SDL_GetError());
exit(1);
}
if ( SDL_VideoDriverName(driver, sizeof(driver)) ) {
printf("Video driver: %s\n", driver);
}
info = SDL_GetVideoInfo();
printf(
"Current display: %dx%d, %d bits-per-pixel\n",
info->current_w, info->current_h, info->vfmt->BitsPerPixel);
if ( info->vfmt->palette == NULL ) {
printf(" Red Mask = 0x%.8x\n", info->vfmt->Rmask);
printf(" Green Mask = 0x%.8x\n", info->vfmt->Gmask);
printf(" Blue Mask = 0x%.8x\n", info->vfmt->Bmask);
}
/* Print available fullscreen video modes */
modes = SDL_ListModes(NULL, SDL_FULLSCREEN);
if ( modes == (SDL_Rect **)0 ) {
printf("No available fullscreen video modes\n");
} else
if ( modes == (SDL_Rect **)-1 ) {
printf("No special fullscreen video modes\n");
} else {
printf("Fullscreen video modes:\n");
for ( i=0; modes[i]; ++i ) {
printf("\t%dx%dx%d\n", modes[i]->w, modes[i]->h, info->vfmt->BitsPerPixel);
}
}
if ( info->wm_available ) {
printf("A window manager is available\n");
}
if ( info->hw_available ) {
printf("Hardware surfaces are available (%dK video memory)\n",
info->video_mem);
}
if ( info->blit_hw ) {
printf(
"Copy blits between hardware surfaces are accelerated\n");
}
if ( info->blit_hw_CC ) {
printf(
"Colorkey blits between hardware surfaces are accelerated\n");
}
if ( info->blit_hw_A ) {
printf(
"Alpha blits between hardware surfaces are accelerated\n");
}
if ( info->blit_sw ) {
printf(
"Copy blits from software surfaces to hardware surfaces are accelerated\n");
}
if ( info->blit_sw_CC ) {
printf(
"Colorkey blits from software surfaces to hardware surfaces are accelerated\n");
}
if ( info->blit_sw_A ) {
printf(
"Alpha blits from software surfaces to hardware surfaces are accelerated\n");
}
if ( info->blit_fill ) {
printf(
"Color fills on hardware surfaces are accelerated\n");
}
if ( argv[1] && (strcmp(argv[1], "-benchmark") == 0) ) {
RunVideoTests();
}
SDL_Quit();
return(0);
}

View File

@ -0,0 +1,377 @@
/* Bring up a window and play with it */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define BENCHMARK_SDL
#define NOTICE(X) printf("%s", X);
#include "SDL.h"
/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
static void quit(int rc)
{
SDL_Quit();
exit(rc);
}
void DrawPict(SDL_Surface *screen, char *bmpfile,
int speedy, int flip, int nofade)
{
SDL_Surface *picture;
SDL_Rect dest, update;
int i, centered;
int ncolors;
SDL_Color *colors, *cmap;
/* Load the image into a surface */
if ( bmpfile == NULL ) {
bmpfile = "sample.bmp"; /* Sample image */
}
fprintf(stderr, "Loading picture: %s\n", bmpfile);
picture = SDL_LoadBMP(bmpfile);
if ( picture == NULL ) {
fprintf(stderr, "Couldn't load %s: %s\n", bmpfile,
SDL_GetError());
return;
}
/* Set the display colors -- on a hicolor display this is a no-op */
if ( picture->format->palette ) {
ncolors = picture->format->palette->ncolors;
colors = (SDL_Color *)malloc(ncolors*sizeof(SDL_Color));
cmap = (SDL_Color *)malloc(ncolors*sizeof(SDL_Color));
memcpy(colors, picture->format->palette->colors,
ncolors*sizeof(SDL_Color));
} else {
int r, g, b;
/* Allocate 256 color palette */
ncolors = 256;
colors = (SDL_Color *)malloc(ncolors*sizeof(SDL_Color));
cmap = (SDL_Color *)malloc(ncolors*sizeof(SDL_Color));
/* Set a 3,3,2 color cube */
for ( r=0; r<8; ++r ) {
for ( g=0; g<8; ++g ) {
for ( b=0; b<4; ++b ) {
i = ((r<<5)|(g<<2)|b);
colors[i].r = r<<5;
colors[i].g = g<<5;
colors[i].b = b<<6;
}
}
}
}
NOTICE("testwin: setting colors\n");
if ( ! SDL_SetColors(screen, colors, 0, ncolors) &&
(screen->format->palette != NULL) ) {
fprintf(stderr,
"Warning: Couldn't set all of the colors, but SDL will map the image\n"
" (colormap fading will suffer - try the -warp option)\n"
);
}
/* Set the screen to black (not really necessary) */
if ( SDL_LockSurface(screen) == 0 ) {
Uint32 black;
Uint8 *pixels;
black = SDL_MapRGB(screen->format, 0, 0, 0);
pixels = (Uint8 *)screen->pixels;
for ( i=0; i<screen->h; ++i ) {
memset(pixels, black,
screen->w*screen->format->BytesPerPixel);
pixels += screen->pitch;
}
SDL_UnlockSurface(screen);
SDL_UpdateRect(screen, 0, 0, 0, 0);
}
/* Display the picture */
if ( speedy ) {
SDL_Surface *displayfmt;
fprintf(stderr, "Converting picture\n");
displayfmt = SDL_DisplayFormat(picture);
if ( displayfmt == NULL ) {
fprintf(stderr,
"Couldn't convert image: %s\n", SDL_GetError());
goto done;
}
SDL_FreeSurface(picture);
picture = displayfmt;
}
printf("(image surface located in %s memory)\n",
(picture->flags&SDL_HWSURFACE) ? "video" : "system");
centered = (screen->w - picture->w)/2;
if ( centered < 0 ) {
centered = 0;
}
dest.y = (screen->h - picture->h)/2;
dest.w = picture->w;
dest.h = picture->h;
NOTICE("testwin: moving image\n");
for ( i=0; i<=centered; ++i ) {
dest.x = i;
update = dest;
if ( SDL_BlitSurface(picture, NULL, screen, &update) < 0 ) {
fprintf(stderr, "Blit failed: %s\n", SDL_GetError());
break;
}
if ( flip ) {
SDL_Flip(screen);
} else {
SDL_UpdateRects(screen, 1, &update);
}
}
#ifdef SCREENSHOT
if ( SDL_SaveBMP(screen, "screen.bmp") < 0 )
printf("Couldn't save screen: %s\n", SDL_GetError());
#endif
#ifndef BENCHMARK_SDL
/* Let it sit there for a while */
SDL_Delay(5*1000);
#endif
/* Fade the colormap */
if ( ! nofade ) {
int maxstep;
SDL_Color final;
SDL_Color palcolors[256];
struct {
Sint16 r, g, b;
} cdist[256];
NOTICE("testwin: fading out...\n");
memcpy(cmap, colors, ncolors*sizeof(SDL_Color));
maxstep = 32-1;
final.r = 0xFF;
final.g = 0x00;
final.b = 0x00;
memcpy(palcolors, colors, ncolors*sizeof(SDL_Color));
for ( i=0; i<ncolors; ++i ) {
cdist[i].r = final.r-palcolors[i].r;
cdist[i].g = final.g-palcolors[i].g;
cdist[i].b = final.b-palcolors[i].b;
}
for ( i=0; i<=maxstep/2; ++i ) { /* halfway fade */
int c;
for ( c=0; c<ncolors; ++c ) {
colors[c].r =
palcolors[c].r+((cdist[c].r*i))/maxstep;
colors[c].g =
palcolors[c].g+((cdist[c].g*i))/maxstep;
colors[c].b =
palcolors[c].b+((cdist[c].b*i))/maxstep;
}
SDL_SetColors(screen, colors, 0, ncolors);
SDL_Delay(1);
}
final.r = 0x00;
final.g = 0x00;
final.b = 0x00;
memcpy(palcolors, colors, ncolors*sizeof(SDL_Color));
for ( i=0; i<ncolors; ++i ) {
cdist[i].r = final.r-palcolors[i].r;
cdist[i].g = final.g-palcolors[i].g;
cdist[i].b = final.b-palcolors[i].b;
}
maxstep /= 2;
for ( i=0; i<=maxstep; ++i ) { /* finish fade out */
int c;
for ( c=0; c<ncolors; ++c ) {
colors[c].r =
palcolors[c].r+((cdist[c].r*i))/maxstep;
colors[c].g =
palcolors[c].g+((cdist[c].g*i))/maxstep;
colors[c].b =
palcolors[c].b+((cdist[c].b*i))/maxstep;
}
SDL_SetColors(screen, colors, 0, ncolors);
SDL_Delay(1);
}
for ( i=0; i<ncolors; ++i ) {
colors[i].r = final.r;
colors[i].g = final.g;
colors[i].b = final.b;
}
SDL_SetColors(screen, colors, 0, ncolors);
NOTICE("testwin: fading in...\n");
memcpy(palcolors, colors, ncolors*sizeof(SDL_Color));
for ( i=0; i<ncolors; ++i ) {
cdist[i].r = cmap[i].r-palcolors[i].r;
cdist[i].g = cmap[i].g-palcolors[i].g;
cdist[i].b = cmap[i].b-palcolors[i].b;
}
for ( i=0; i<=maxstep; ++i ) { /* 32 step fade in */
int c;
for ( c=0; c<ncolors; ++c ) {
colors[c].r =
palcolors[c].r+((cdist[c].r*i))/maxstep;
colors[c].g =
palcolors[c].g+((cdist[c].g*i))/maxstep;
colors[c].b =
palcolors[c].b+((cdist[c].b*i))/maxstep;
}
SDL_SetColors(screen, colors, 0, ncolors);
SDL_Delay(1);
}
NOTICE("testwin: fading over\n");
}
done:
/* Free the picture and return */
SDL_FreeSurface(picture);
free(colors); free(cmap);
return;
}
int main(int argc, char *argv[])
{
SDL_Surface *screen;
/* Options */
int speedy, flip, nofade;
int delay;
int w, h;
int desired_bpp;
Uint32 video_flags;
#ifdef BENCHMARK_SDL
Uint32 then, now;
#endif
/* Set default options and check command-line */
speedy = 0;
flip = 0;
nofade = 0;
delay = 1;
#ifdef _WIN32_WCE
w = 240;
h = 320;
desired_bpp = 8;
video_flags = SDL_FULLSCREEN;
#else
w = 640;
h = 480;
desired_bpp = 0;
video_flags = 0;
#endif
if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
fprintf(stderr,
"Couldn't initialize SDL: %s\n", SDL_GetError());
return(1);
}
while ( argc > 1 ) {
if ( strcmp(argv[1], "-speedy") == 0 ) {
speedy = 1;
argv += 1;
argc -= 1;
} else
if ( strcmp(argv[1], "-nofade") == 0 ) {
nofade = 1;
argv += 1;
argc -= 1;
} else
if ( strcmp(argv[1], "-delay") == 0 ) {
if ( argv[2] ) {
delay = atoi(argv[2]);
argv += 2;
argc -= 2;
} else {
fprintf(stderr,
"The -delay option requires an argument\n");
quit(1);
}
} else
if ( strcmp(argv[1], "-width") == 0 ) {
if ( argv[2] && ((w = atoi(argv[2])) > 0) ) {
argv += 2;
argc -= 2;
} else {
fprintf(stderr,
"The -width option requires an argument\n");
quit(1);
}
} else
if ( strcmp(argv[1], "-height") == 0 ) {
if ( argv[2] && ((h = atoi(argv[2])) > 0) ) {
argv += 2;
argc -= 2;
} else {
fprintf(stderr,
"The -height option requires an argument\n");
quit(1);
}
} else
if ( strcmp(argv[1], "-bpp") == 0 ) {
if ( argv[2] ) {
desired_bpp = atoi(argv[2]);
argv += 2;
argc -= 2;
} else {
fprintf(stderr,
"The -bpp option requires an argument\n");
quit(1);
}
} else
if ( strcmp(argv[1], "-warp") == 0 ) {
video_flags |= SDL_HWPALETTE;
argv += 1;
argc -= 1;
} else
if ( strcmp(argv[1], "-hw") == 0 ) {
video_flags |= SDL_HWSURFACE;
argv += 1;
argc -= 1;
} else
if ( strcmp(argv[1], "-flip") == 0 ) {
video_flags |= SDL_DOUBLEBUF;
argv += 1;
argc -= 1;
} else
if ( strcmp(argv[1], "-fullscreen") == 0 ) {
video_flags |= SDL_FULLSCREEN;
argv += 1;
argc -= 1;
} else
break;
}
/* Initialize the display */
screen = SDL_SetVideoMode(w, h, desired_bpp, video_flags);
if ( screen == NULL ) {
fprintf(stderr, "Couldn't set %dx%dx%d video mode: %s\n",
w, h, desired_bpp, SDL_GetError());
quit(1);
}
printf("Set%s %dx%dx%d mode\n",
screen->flags & SDL_FULLSCREEN ? " fullscreen" : "",
screen->w, screen->h, screen->format->BitsPerPixel);
printf("(video surface located in %s memory)\n",
(screen->flags&SDL_HWSURFACE) ? "video" : "system");
if ( screen->flags & SDL_DOUBLEBUF ) {
printf("Double-buffering enabled\n");
flip = 1;
}
/* Set the window manager title bar */
SDL_WM_SetCaption("SDL test window", "testwin");
/* Do all the drawing work */
#ifdef BENCHMARK_SDL
then = SDL_GetTicks();
DrawPict(screen, argv[1], speedy, flip, nofade);
now = SDL_GetTicks();
printf("Time: %d milliseconds\n", now-then);
#else
DrawPict(screen, argv[1], speedy, flip, nofade);
#endif
SDL_Delay(delay*1000);
SDL_Quit();
return(0);
}

View File

@ -0,0 +1,443 @@
/* Test out the window manager interaction functions */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "SDL.h"
/* Is the cursor visible? */
static int visible = 1;
static Uint8 video_bpp;
static Uint32 video_flags;
/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
static void quit(int rc)
{
SDL_Quit();
exit(rc);
}
int SetVideoMode(int w, int h)
{
SDL_Surface *screen;
int i;
Uint8 *buffer;
SDL_Color palette[256];
screen = SDL_SetVideoMode(w, h, video_bpp, video_flags);
if ( screen == NULL ) {
fprintf(stderr, "Couldn't set %dx%dx%d video mode: %s\n",
w, h, video_bpp, SDL_GetError());
return(-1);
}
printf("Running in %s mode\n", screen->flags & SDL_FULLSCREEN ?
"fullscreen" : "windowed");
/* Set the surface pixels and refresh! */
for ( i=0; i<256; ++i ) {
palette[i].r = 255-i;
palette[i].g = 255-i;
palette[i].b = 255-i;
}
SDL_SetColors(screen, palette, 0, 256);
if ( SDL_LockSurface(screen) < 0 ) {
fprintf(stderr, "Couldn't lock display surface: %s\n",
SDL_GetError());
return(-1);
}
buffer = (Uint8 *)screen->pixels;
for ( i=0; i<screen->h; ++i ) {
memset(buffer,(i*255)/screen->h,
screen->w*screen->format->BytesPerPixel);
buffer += screen->pitch;
}
SDL_UnlockSurface(screen);
SDL_UpdateRect(screen, 0, 0, 0, 0);
return(0);
}
SDL_Surface *LoadIconSurface(char *file, Uint8 **maskp)
{
SDL_Surface *icon;
Uint8 *pixels;
Uint8 *mask;
int mlen, i, j;
*maskp = NULL;
/* Load the icon surface */
icon = SDL_LoadBMP(file);
if ( icon == NULL ) {
fprintf(stderr, "Couldn't load %s: %s\n", file, SDL_GetError());
return(NULL);
}
/* Check width and height
if ( (icon->w%8) != 0 ) {
fprintf(stderr, "Icon width must be a multiple of 8!\n");
SDL_FreeSurface(icon);
return(NULL);
}
*/
if ( icon->format->palette == NULL ) {
fprintf(stderr, "Icon must have a palette!\n");
SDL_FreeSurface(icon);
return(NULL);
}
/* Set the colorkey */
SDL_SetColorKey(icon, SDL_SRCCOLORKEY, *((Uint8 *)icon->pixels));
/* Create the mask */
pixels = (Uint8 *)icon->pixels;
printf("Transparent pixel: (%d,%d,%d)\n",
icon->format->palette->colors[*pixels].r,
icon->format->palette->colors[*pixels].g,
icon->format->palette->colors[*pixels].b);
mlen = (icon->w*icon->h + 7) / 8;
mask = (Uint8 *)malloc(mlen);
if ( mask == NULL ) {
fprintf(stderr, "Out of memory!\n");
SDL_FreeSurface(icon);
return(NULL);
}
memset(mask, 0, mlen);
for ( i=0; i < icon->h; i++)
for (j=0; j < icon->w; j++) {
int pindex = i * icon->pitch + j;
int mindex = i * icon->w + j;
if ( pixels[pindex] != *pixels )
mask[mindex>>3] |= 1 << (7 - (mindex & 7));
}
*maskp = mask;
return(icon);
}
void HotKey_ToggleFullScreen(void)
{
SDL_Surface *screen;
screen = SDL_GetVideoSurface();
if ( SDL_WM_ToggleFullScreen(screen) ) {
printf("Toggled fullscreen mode - now %s\n",
(screen->flags&SDL_FULLSCREEN) ? "fullscreen" : "windowed");
} else {
printf("Unable to toggle fullscreen mode\n");
video_flags ^= SDL_FULLSCREEN;
SetVideoMode(screen->w, screen->h);
}
}
void HotKey_ToggleGrab(void)
{
SDL_GrabMode mode;
printf("Ctrl-G: toggling input grab!\n");
mode = SDL_WM_GrabInput(SDL_GRAB_QUERY);
if ( mode == SDL_GRAB_ON ) {
printf("Grab was on\n");
} else {
printf("Grab was off\n");
}
mode = SDL_WM_GrabInput(mode ? SDL_GRAB_OFF : SDL_GRAB_ON);
if ( mode == SDL_GRAB_ON ) {
printf("Grab is now on\n");
} else {
printf("Grab is now off\n");
}
}
void HotKey_Iconify(void)
{
printf("Ctrl-Z: iconifying window!\n");
SDL_WM_IconifyWindow();
}
void HotKey_Quit(void)
{
SDL_Event event;
printf("Posting internal quit request\n");
event.type = SDL_USEREVENT;
SDL_PushEvent(&event);
}
static void print_modifiers(void)
{
int mod;
printf(" modifiers:");
mod = SDL_GetModState();
if(!mod) {
printf(" (none)");
return;
}
if(mod & KMOD_LSHIFT)
printf(" LSHIFT");
if(mod & KMOD_RSHIFT)
printf(" RSHIFT");
if(mod & KMOD_LCTRL)
printf(" LCTRL");
if(mod & KMOD_RCTRL)
printf(" RCTRL");
if(mod & KMOD_LALT)
printf(" LALT");
if(mod & KMOD_RALT)
printf(" RALT");
if(mod & KMOD_LMETA)
printf(" LMETA");
if(mod & KMOD_RMETA)
printf(" RMETA");
if(mod & KMOD_NUM)
printf(" NUM");
if(mod & KMOD_CAPS)
printf(" CAPS");
if(mod & KMOD_MODE)
printf(" MODE");
}
static void PrintKey(const SDL_keysym *sym, int pressed)
{
/* Print the keycode, name and state */
if ( sym->sym ) {
printf("Key %s: %d-%s ", pressed ? "pressed" : "released",
sym->sym, SDL_GetKeyName(sym->sym));
} else {
printf("Unknown Key (scancode = %d) %s ", sym->scancode,
pressed ? "pressed" : "released");
}
/* Print the translated character, if one exists */
if ( sym->unicode ) {
/* Is it a control-character? */
if ( sym->unicode < ' ' ) {
printf(" (^%c)", sym->unicode+'@');
} else {
#ifdef UNICODE
printf(" (%c)", sym->unicode);
#else
/* This is a Latin-1 program, so only show 8-bits */
if ( !(sym->unicode & 0xFF00) )
printf(" (%c)", sym->unicode);
else
printf(" (0x%X)", sym->unicode);
#endif
}
}
print_modifiers();
printf("\n");
}
int SDLCALL FilterEvents(const SDL_Event *event)
{
static int reallyquit = 0;
switch (event->type) {
case SDL_ACTIVEEVENT:
/* See what happened */
printf("App %s ",
event->active.gain ? "gained" : "lost");
if ( event->active.state & SDL_APPACTIVE )
printf("active ");
if ( event->active.state & SDL_APPINPUTFOCUS )
printf("input ");
if ( event->active.state & SDL_APPMOUSEFOCUS )
printf("mouse ");
printf("focus\n");
/* See if we are iconified or restored */
if ( event->active.state & SDL_APPACTIVE ) {
printf("App has been %s\n",
event->active.gain ?
"restored" : "iconified");
}
return(0);
/* We want to toggle visibility on buttonpress */
case SDL_MOUSEBUTTONDOWN:
case SDL_MOUSEBUTTONUP:
if ( event->button.state == SDL_PRESSED ) {
visible = !visible;
SDL_ShowCursor(visible);
}
printf("Mouse button %d has been %s\n",
event->button.button,
(event->button.state == SDL_PRESSED) ?
"pressed" : "released");
return(0);
/* Show relative mouse motion */
case SDL_MOUSEMOTION:
#if 0
printf("Mouse motion: {%d,%d} (%d,%d)\n",
event->motion.x, event->motion.y,
event->motion.xrel, event->motion.yrel);
#endif
return(0);
case SDL_KEYDOWN:
PrintKey(&event->key.keysym, 1);
if ( event->key.keysym.sym == SDLK_ESCAPE ) {
HotKey_Quit();
}
if ( (event->key.keysym.sym == SDLK_g) &&
(event->key.keysym.mod & KMOD_CTRL) ) {
HotKey_ToggleGrab();
}
if ( (event->key.keysym.sym == SDLK_z) &&
(event->key.keysym.mod & KMOD_CTRL) ) {
HotKey_Iconify();
}
if ( (event->key.keysym.sym == SDLK_RETURN) &&
(event->key.keysym.mod & KMOD_ALT) ) {
HotKey_ToggleFullScreen();
}
return(0);
case SDL_KEYUP:
PrintKey(&event->key.keysym, 0);
return(0);
/* Pass the video resize event through .. */
case SDL_VIDEORESIZE:
return(1);
/* This is important! Queue it if we want to quit. */
case SDL_QUIT:
if ( ! reallyquit ) {
reallyquit = 1;
printf("Quit requested\n");
return(0);
}
printf("Quit demanded\n");
return(1);
/* This will never happen because events queued directly
to the event queue are not filtered.
*/
case SDL_USEREVENT:
return(1);
/* Drop all other events */
default:
return(0);
}
}
int main(int argc, char *argv[])
{
SDL_Event event;
char *title;
SDL_Surface *icon;
Uint8 *icon_mask;
int parsed;
int w, h;
if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
fprintf(stderr,
"Couldn't initialize SDL: %s\n", SDL_GetError());
return(1);
}
/* Check command line arguments */
w = 640;
h = 480;
video_bpp = 8;
video_flags = SDL_SWSURFACE;
parsed = 1;
while ( parsed ) {
if ( (argc >= 2) && (strcmp(argv[1], "-fullscreen") == 0) ) {
video_flags |= SDL_FULLSCREEN;
argc -= 1;
argv += 1;
} else
if ( (argc >= 2) && (strcmp(argv[1], "-resize") == 0) ) {
video_flags |= SDL_RESIZABLE;
argc -= 1;
argv += 1;
} else
if ( (argc >= 2) && (strcmp(argv[1], "-noframe") == 0) ) {
video_flags |= SDL_NOFRAME;
argc -= 1;
argv += 1;
} else
if ( (argc >= 3) && (strcmp(argv[1], "-width") == 0) ) {
w = atoi(argv[2]);
argc -= 2;
argv += 2;
} else
if ( (argc >= 3) && (strcmp(argv[1], "-height") == 0) ) {
h = atoi(argv[2]);
argc -= 2;
argv += 2;
} else
if ( (argc >= 3) && (strcmp(argv[1], "-bpp") == 0) ) {
video_bpp = atoi(argv[2]);
argc -= 2;
argv += 2;
} else {
parsed = 0;
}
}
/* Set the icon -- this must be done before the first mode set */
icon = LoadIconSurface("icon.bmp", &icon_mask);
if ( icon != NULL ) {
SDL_WM_SetIcon(icon, icon_mask);
}
if ( icon_mask != NULL )
free(icon_mask);
/* Set the title bar */
if ( argv[1] == NULL )
title = "Testing 1.. 2.. 3...";
else
title = argv[1];
SDL_WM_SetCaption(title, "testwm");
/* See if it's really set */
SDL_WM_GetCaption(&title, NULL);
if ( title )
printf("Title was set to: %s\n", title);
else
printf("No window title was set!\n");
/* Initialize the display */
if ( SetVideoMode(w, h) < 0 ) {
quit(1);
}
/* Set an event filter that discards everything but QUIT */
SDL_SetEventFilter(FilterEvents);
/* Loop, waiting for QUIT */
while ( SDL_WaitEvent(&event) ) {
switch (event.type) {
case SDL_VIDEORESIZE:
printf("Got a resize event: %dx%d\n",
event.resize.w, event.resize.h);
SetVideoMode(event.resize.w, event.resize.h);
break;
case SDL_USEREVENT:
printf("Handling internal quit request\n");
/* Fall through to the quit handler */
case SDL_QUIT:
printf("Bye bye..\n");
quit(0);
default:
/* This should never happen */
printf("Warning: Event %d wasn't filtered\n",
event.type);
break;
}
}
printf("SDL_WaitEvent() error: %s\n", SDL_GetError());
SDL_Quit();
return(255);
}

View File

@ -0,0 +1,338 @@
/* Test out the multi-threaded event handling functions */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "SDL.h"
#include "SDL_thread.h"
/* Are we done yet? */
static int done = 0;
/* Is the cursor visible? */
static int visible = 1;
/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
static void quit(int rc)
{
SDL_Quit();
exit(rc);
}
SDL_Surface *LoadIconSurface(char *file, Uint8 **maskp)
{
SDL_Surface *icon;
Uint8 *pixels;
Uint8 *mask;
int mlen, i;
*maskp = NULL;
/* Load the icon surface */
icon = SDL_LoadBMP(file);
if ( icon == NULL ) {
fprintf(stderr, "Couldn't load %s: %s\n", file, SDL_GetError());
return(NULL);
}
/* Check width and height */
if ( (icon->w%8) != 0 ) {
fprintf(stderr, "Icon width must be a multiple of 8!\n");
SDL_FreeSurface(icon);
return(NULL);
}
if ( icon->format->palette == NULL ) {
fprintf(stderr, "Icon must have a palette!\n");
SDL_FreeSurface(icon);
return(NULL);
}
/* Set the colorkey */
SDL_SetColorKey(icon, SDL_SRCCOLORKEY, *((Uint8 *)icon->pixels));
/* Create the mask */
pixels = (Uint8 *)icon->pixels;
printf("Transparent pixel: (%d,%d,%d)\n",
icon->format->palette->colors[*pixels].r,
icon->format->palette->colors[*pixels].g,
icon->format->palette->colors[*pixels].b);
mlen = icon->w*icon->h;
mask = (Uint8 *)malloc(mlen/8);
if ( mask == NULL ) {
fprintf(stderr, "Out of memory!\n");
SDL_FreeSurface(icon);
return(NULL);
}
memset(mask, 0, mlen/8);
for ( i=0; i<mlen; ) {
if ( pixels[i] != *pixels )
mask[i/8] |= 0x01;
++i;
if ( (i%8) != 0 )
mask[i/8] <<= 1;
}
*maskp = mask;
return(icon);
}
int SDLCALL FilterEvents(const SDL_Event *event)
{
static int reallyquit = 0;
switch (event->type) {
case SDL_ACTIVEEVENT:
/* See what happened */
printf("App %s ",
event->active.gain ? "gained" : "lost");
if ( event->active.state & SDL_APPACTIVE )
printf("active ");
if ( event->active.state & SDL_APPMOUSEFOCUS )
printf("mouse ");
if ( event->active.state & SDL_APPINPUTFOCUS )
printf("input ");
printf("focus\n");
/* See if we are iconified or restored */
if ( event->active.state & SDL_APPACTIVE ) {
printf("App has been %s\n",
event->active.gain ?
"restored" : "iconified");
}
return(0);
/* This is important! Queue it if we want to quit. */
case SDL_QUIT:
if ( ! reallyquit ) {
reallyquit = 1;
printf("Quit requested\n");
return(0);
}
printf("Quit demanded\n");
return(1);
/* Mouse and keyboard events go to threads */
case SDL_MOUSEMOTION:
case SDL_MOUSEBUTTONDOWN:
case SDL_MOUSEBUTTONUP:
case SDL_KEYDOWN:
case SDL_KEYUP:
return(1);
/* Drop all other events */
default:
return(0);
}
}
int SDLCALL HandleMouse(void *unused)
{
SDL_Event events[10];
int i, found;
Uint32 mask;
/* Handle mouse events here */
mask = (SDL_MOUSEMOTIONMASK|SDL_MOUSEBUTTONDOWNMASK|SDL_MOUSEBUTTONUPMASK);
while ( ! done ) {
found = SDL_PeepEvents(events, 10, SDL_GETEVENT, mask);
for ( i=0; i<found; ++i ) {
switch(events[i].type) {
/* We want to toggle visibility on buttonpress */
case SDL_MOUSEBUTTONDOWN:
case SDL_MOUSEBUTTONUP:
if ( events[i].button.state == SDL_PRESSED ) {
visible = !visible;
SDL_ShowCursor(visible);
}
printf("Mouse button %d has been %s\n",
events[i].button.button,
(events[i].button.state == SDL_PRESSED) ?
"pressed" : "released");
break;
/* Show relative mouse motion */
case SDL_MOUSEMOTION:
printf("Mouse relative motion: {%d,%d}\n",
events[i].motion.xrel, events[i].motion.yrel);
break;
}
}
/* Give up some CPU to allow events to arrive */
SDL_Delay(20);
}
return(0);
}
int SDLCALL HandleKeyboard(void *unused)
{
SDL_Event events[10];
int i, found;
Uint32 mask;
/* Handle mouse events here */
mask = (SDL_KEYDOWNMASK|SDL_KEYUPMASK);
while ( ! done ) {
found = SDL_PeepEvents(events, 10, SDL_GETEVENT, mask);
for ( i=0; i<found; ++i ) {
switch(events[i].type) {
/* We want to toggle visibility on buttonpress */
case SDL_KEYDOWN:
case SDL_KEYUP:
printf("Key '%c' (keysym==%d) has been %s\n",
events[i].key.keysym.unicode,
(int) events[i].key.keysym.sym,
(events[i].key.state == SDL_PRESSED) ?
"pressed" : "released");
/* Allow hitting <ESC> to quit the app */
if ( events[i].key.keysym.sym == SDLK_ESCAPE ) {
done = 1;
}
/* skip events now that aren't KEYUPs... */
if (events[i].key.state == SDL_PRESSED)
break;
if ( events[i].key.keysym.sym == SDLK_f ) {
int rc = 0;
printf("attempting to toggle fullscreen...\n");
rc = SDL_WM_ToggleFullScreen(SDL_GetVideoSurface());
printf("SDL_WM_ToggleFullScreen returned %d.\n", rc);
}
if ( events[i].key.keysym.sym == SDLK_g ) {
SDL_GrabMode m;
m = SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_ON ?
SDL_GRAB_OFF : SDL_GRAB_ON;
printf("attempting to toggle input grab to %s...\n",
m == SDL_GRAB_ON ? "ON" : "OFF");
SDL_WM_GrabInput(m);
printf("attempt finished.\n");
}
break;
}
}
/* Give up some CPU to allow events to arrive */
SDL_Delay(20);
}
return(0);
}
int main(int argc, char *argv[])
{
SDL_Surface *screen;
SDL_Surface *icon;
Uint8 *icon_mask;
int i, parsed;
Uint8 *buffer;
SDL_Color palette[256];
Uint32 init_flags;
Uint8 video_bpp;
Uint32 video_flags;
SDL_Thread *mouse_thread;
SDL_Thread *keybd_thread;
/* Set the options, based on command line arguments */
init_flags = SDL_INIT_VIDEO;
video_bpp = 8;
video_flags = SDL_SWSURFACE;
parsed = 1;
while ( parsed ) {
/* If the threaded option is enabled, and the SDL library hasn't
been compiled with threaded events enabled, then the mouse and
keyboard won't respond.
*/
if ( (argc >= 2) && (strcmp(argv[1], "-threaded") == 0) ) {
init_flags |= SDL_INIT_EVENTTHREAD;
argc -= 1;
argv += 1;
printf("Running with threaded events\n");
} else
if ( (argc >= 2) && (strcmp(argv[1], "-fullscreen") == 0) ) {
video_flags |= SDL_FULLSCREEN;
argc -= 1;
argv += 1;
} else
if ( (argc >= 3) && (strcmp(argv[1], "-bpp") == 0) ) {
video_bpp = atoi(argv[2]);
argc -= 2;
argv += 2;
} else {
parsed = 0;
}
}
/* Initialize SDL with the requested flags */
if ( SDL_Init(init_flags) < 0 ) {
fprintf(stderr,
"Couldn't initialize SDL: %s\n", SDL_GetError());
return(1);
}
/* Set the icon -- this must be done before the first mode set */
icon = LoadIconSurface("icon.bmp", &icon_mask);
if ( icon != NULL ) {
SDL_WM_SetIcon(icon, icon_mask);
}
if ( icon_mask != NULL )
free(icon_mask);
/* Initialize the display */
screen = SDL_SetVideoMode(640, 480, video_bpp, video_flags);
if ( screen == NULL ) {
fprintf(stderr, "Couldn't set 640x480x%d video mode: %s\n",
video_bpp, SDL_GetError());
quit(1);
}
printf("Running in %s mode\n", screen->flags & SDL_FULLSCREEN ?
"fullscreen" : "windowed");
/* Enable printable characters */
SDL_EnableUNICODE(1);
/* Set an event filter that discards everything but QUIT */
SDL_SetEventFilter(FilterEvents);
/* Create the event handling threads */
mouse_thread = SDL_CreateThread(HandleMouse, NULL);
keybd_thread = SDL_CreateThread(HandleKeyboard, NULL);
/* Set the surface pixels and refresh! */
for ( i=0; i<256; ++i ) {
palette[i].r = 255-i;
palette[i].g = 255-i;
palette[i].b = 255-i;
}
SDL_SetColors(screen, palette, 0, 256);
if ( SDL_LockSurface(screen) < 0 ) {
fprintf(stderr, "Couldn't lock display surface: %s\n",
SDL_GetError());
quit(2);
}
buffer = (Uint8 *)screen->pixels;
for ( i=0; i<screen->h; ++i ) {
memset(buffer,(i*255)/screen->h,
screen->w*screen->format->BytesPerPixel);
buffer += screen->pitch;
}
SDL_UnlockSurface(screen);
SDL_UpdateRect(screen, 0, 0, 0, 0);
/* Loop, waiting for QUIT */
while ( ! done ) {
if ( ! (init_flags & SDL_INIT_EVENTTHREAD) ) {
SDL_PumpEvents(); /* Needed when event thread is off */
}
if ( SDL_PeepEvents(NULL, 0, SDL_PEEKEVENT, SDL_QUITMASK) ) {
done = 1;
}
/* Give up some CPU so the events can accumulate */
SDL_Delay(20);
}
SDL_WaitThread(mouse_thread, NULL);
SDL_WaitThread(keybd_thread, NULL);
SDL_Quit();
return(0);
}

View File

@ -0,0 +1,91 @@
/* Simple test of the SDL threading code */
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#include "SDL.h"
#include "SDL_thread.h"
#define NUMTHREADS 10
static char volatile time_for_threads_to_die[NUMTHREADS];
/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
static void quit(int rc)
{
SDL_Quit();
exit(rc);
}
int SDLCALL SubThreadFunc(void *data) {
while(! *(int volatile *)data) {
; /*SDL_Delay(10);*/ /* do nothing */
}
return 0;
}
int SDLCALL ThreadFunc(void *data) {
SDL_Thread *sub_threads[NUMTHREADS];
int flags[NUMTHREADS];
int i;
int tid = (int)(uintptr_t)data;
fprintf(stderr, "Creating Thread %d\n", tid);
for(i = 0; i < NUMTHREADS; i++) {
flags[i] = 0;
sub_threads[i] = SDL_CreateThread(SubThreadFunc, &flags[i]);
}
printf("Thread '%d' waiting for signal\n", tid);
while(time_for_threads_to_die[tid] != 1) {
; /* do nothing */
}
printf("Thread '%d' sending signals to subthreads\n", tid);
for(i = 0; i < NUMTHREADS; i++) {
flags[i] = 1;
SDL_WaitThread(sub_threads[i], NULL);
}
printf("Thread '%d' exiting!\n", tid);
return 0;
}
int main(int argc, char *argv[])
{
SDL_Thread *threads[NUMTHREADS];
int i;
/* Load the SDL library */
if ( SDL_Init(0) < 0 ) {
fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError());
return(1);
}
signal(SIGSEGV, SIG_DFL);
for(i = 0; i < NUMTHREADS; i++) {
time_for_threads_to_die[i] = 0;
threads[i] = SDL_CreateThread(ThreadFunc, (void *)(uintptr_t)i);
if ( threads[i] == NULL ) {
fprintf(stderr,
"Couldn't create thread: %s\n", SDL_GetError());
quit(1);
}
}
for(i = 0; i < NUMTHREADS; i++) {
time_for_threads_to_die[i] = 1;
}
for(i = 0; i < NUMTHREADS; i++) {
SDL_WaitThread(threads[i], NULL);
}
SDL_Quit();
return(0);
}

View File

@ -0,0 +1,287 @@
UTF-8 decoder capability and stress test
----------------------------------------
Markus Kuhn <http://www.cl.cam.ac.uk/~mgk25/> - 2003-02-19
This test file can help you examine, how your UTF-8 decoder handles
various types of correct, malformed, or otherwise interesting UTF-8
sequences. This file is not meant to be a conformance test. It does
not prescribes any particular outcome and therefore there is no way to
"pass" or "fail" this test file, even though the texts suggests a
preferable decoder behaviour at some places. The aim is instead to
help you think about and test the behaviour of your UTF-8 on a
systematic collection of unusual inputs. Experience so far suggests
that most first-time authors of UTF-8 decoders find at least one
serious problem in their decoder by using this file.
The test lines below cover boundary conditions, malformed UTF-8
sequences as well as correctly encoded UTF-8 sequences of Unicode code
points that should never occur in a correct UTF-8 file.
According to ISO 10646-1:2000, sections D.7 and 2.3c, a device
receiving UTF-8 shall interpret a "malformed sequence in the same way
that it interprets a character that is outside the adopted subset" and
"characters that are not within the adopted subset shall be indicated
to the user" by a receiving device. A quite commonly used approach in
UTF-8 decoders is to replace any malformed UTF-8 sequence by a
replacement character (U+FFFD), which looks a bit like an inverted
question mark, or a similar symbol. It might be a good idea to
visually distinguish a malformed UTF-8 sequence from a correctly
encoded Unicode character that is just not available in the current
font but otherwise fully legal, even though ISO 10646-1 doesn't
mandate this. In any case, just ignoring malformed sequences or
unavailable characters does not conform to ISO 10646, will make
debugging more difficult, and can lead to user confusion.
Please check, whether a malformed UTF-8 sequence is (1) represented at
all, (2) represented by exactly one single replacement character (or
equivalent signal), and (3) the following quotation mark after an
illegal UTF-8 sequence is correctly displayed, i.e. proper
resynchronization takes place immageately after any malformed
sequence. This file says "THE END" in the last line, so if you don't
see that, your decoder crashed somehow before, which should always be
cause for concern.
All lines in this file are exactly 79 characters long (plus the line
feed). In addition, all lines end with "|", except for the two test
lines 2.1.1 and 2.2.1, which contain non-printable ASCII controls
U+0000 and U+007F. If you display this file with a fixed-width font,
these "|" characters should all line up in column 79 (right margin).
This allows you to test quickly, whether your UTF-8 decoder finds the
correct number of characters in every line, that is whether each
malformed sequences is replaced by a single replacement character.
Note that as an alternative to the notion of malformed sequence used
here, it is also a perfectly acceptable (and in some situations even
preferable) solution to represent each individual byte of a malformed
sequence by a replacement character. If you follow this strategy in
your decoder, then please ignore the "|" column.
Here come the tests: |
|
1 Some correct UTF-8 text |
|
(The codepoints for this test are: |
U+03BA U+1F79 U+03C3 U+03BC U+03B5 --ryan.) |
|
You should see the Greek word 'kosme': "κόσμε" |
|
|
2 Boundary condition test cases |
|
2.1 First possible sequence of a certain length |
|
(byte zero skipped...there's a null added at the end of the test. --ryan.) |
|
2.1.2 2 bytes (U-00000080): "€" |
2.1.3 3 bytes (U-00000800): "à €" |
2.1.4 4 bytes (U-00010000): "ð<>€€" |
|
(5 and 6 byte sequences were made illegal in rfc3629. --ryan.) |
2.1.5 5 bytes (U-00200000): "øˆ€€€" |
2.1.6 6 bytes (U-04000000): "ü„€€€€" |
|
2.2 Last possible sequence of a certain length |
|
2.2.1 1 byte (U-0000007F): "" |
2.2.2 2 bytes (U-000007FF): "ß¿" |
|
(Section 5.3.2 below calls this illegal. --ryan.) |
2.2.3 3 bytes (U-0000FFFF): "ï¿¿" |
|
(5 and 6 bytes sequences, and 4 bytes sequences > 0x10FFFF were made illegal |
in rfc3629, so these next three should be replaced with a invalid |
character codepoint. --ryan.) |
2.2.4 4 bytes (U-001FFFFF): "÷¿¿¿" |
2.2.5 5 bytes (U-03FFFFFF): "û¿¿¿¿" |
2.2.6 6 bytes (U-7FFFFFFF): "ý¿¿¿¿¿" |
|
2.3 Other boundary conditions |
|
2.3.1 U-0000D7FF = ed 9f bf = "퟿" |
2.3.2 U-0000E000 = ee 80 80 = "" |
2.3.3 U-0000FFFD = ef bf bd = "�" |
2.3.4 U-0010FFFF = f4 8f bf bf = "ô<>¿¿" |
|
(This one is bogus in rfc3629. --ryan.) |
2.3.5 U-00110000 = f4 90 80 80 = "ô<>€€" |
|
3 Malformed sequences |
|
3.1 Unexpected continuation bytes |
|
Each unexpected continuation byte should be separately signalled as a |
malformed sequence of its own. |
|
3.1.1 First continuation byte 0x80: "€" |
3.1.2 Last continuation byte 0xbf: "¿" |
|
3.1.3 2 continuation bytes: "€¿" |
3.1.4 3 continuation bytes: "€¿€" |
3.1.5 4 continuation bytes: "€¿€¿" |
3.1.6 5 continuation bytes: "€¿€¿€" |
3.1.7 6 continuation bytes: "€¿€¿€¿" |
3.1.8 7 continuation bytes: "€¿€¿€¿€" |
|
3.1.9 Sequence of all 64 possible continuation bytes (0x80-0xbf): |
|
"€<>ƒ„…†‡ˆ‰ŠŒ<E280B9>Ž<EFBFBD> |
<20>“”•˜™šœ<E280BA>žŸ |
 ¡¢£¤¥¦§¨©ª«¬­®¯ |
°±²³´µ¶·¸¹º»¼½¾¿" |
|
3.2 Lonely start characters |
|
3.2.1 All 32 first bytes of 2-byte sequences (0xc0-0xdf), |
each followed by a space character: |
|
"À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï |
Ð Ñ Ò Ó Ô Õ Ö × Ø Ù Ú Û Ü Ý Þ ß " |
|
3.2.2 All 16 first bytes of 3-byte sequences (0xe0-0xef), |
each followed by a space character: |
|
"à á â ã ä å æ ç è é ê ë ì í î ï " |
|
3.2.3 All 8 first bytes of 4-byte sequences (0xf0-0xf7), |
each followed by a space character: |
|
"ð ñ ò ó ô õ ö ÷ " |
|
3.2.4 All 4 first bytes of 5-byte sequences (0xf8-0xfb), |
each followed by a space character: |
|
"ø ù ú û " |
|
3.2.5 All 2 first bytes of 6-byte sequences (0xfc-0xfd), |
each followed by a space character: |
|
"ü ý " |
|
3.3 Sequences with last continuation byte missing |
|
All bytes of an incomplete sequence should be signalled as a single |
malformed sequence, i.e., you should see only a single replacement |
character in each of the next 10 tests. (Characters as in section 2) |
|
3.3.1 2-byte sequence with last byte missing (U+0000): "À" |
3.3.2 3-byte sequence with last byte missing (U+0000): "à€" |
3.3.3 4-byte sequence with last byte missing (U+0000): "ð€€" |
3.3.4 5-byte sequence with last byte missing (U+0000): "ø€€€" |
3.3.5 6-byte sequence with last byte missing (U+0000): "ü€€€€" |
3.3.6 2-byte sequence with last byte missing (U-000007FF): "ß" |
3.3.7 3-byte sequence with last byte missing (U-0000FFFF): "ï¿" |
3.3.8 4-byte sequence with last byte missing (U-001FFFFF): "÷¿¿" |
3.3.9 5-byte sequence with last byte missing (U-03FFFFFF): "û¿¿¿" |
3.3.10 6-byte sequence with last byte missing (U-7FFFFFFF): "ý¿¿¿¿" |
|
3.4 Concatenation of incomplete sequences |
|
All the 10 sequences of 3.3 concatenated, you should see 10 malformed |
sequences being signalled: |
|
"Àà€ð€€ø€€€ü€€€€ßï¿÷¿¿û¿¿¿ý¿¿¿¿" |
|
3.5 Impossible bytes |
|
The following two bytes cannot appear in a correct UTF-8 string |
|
3.5.1 fe = "þ" |
3.5.2 ff = "ÿ" |
3.5.3 fe fe ff ff = "þþÿÿ" |
|
4 Overlong sequences |
|
The following sequences are not malformed according to the letter of |
the Unicode 2.0 standard. However, they are longer then necessary and |
a correct UTF-8 encoder is not allowed to produce them. A "safe UTF-8 |
decoder" should reject them just like malformed sequences for two |
reasons: (1) It helps to debug applications if overlong sequences are |
not treated as valid representations of characters, because this helps |
to spot problems more quickly. (2) Overlong sequences provide |
alternative representations of characters, that could maliciously be |
used to bypass filters that check only for ASCII characters. For |
instance, a 2-byte encoded line feed (LF) would not be caught by a |
line counter that counts only 0x0a bytes, but it would still be |
processed as a line feed by an unsafe UTF-8 decoder later in the |
pipeline. From a security point of view, ASCII compatibility of UTF-8 |
sequences means also, that ASCII characters are *only* allowed to be |
represented by ASCII bytes in the range 0x00-0x7f. To ensure this |
aspect of ASCII compatibility, use only "safe UTF-8 decoders" that |
reject overlong UTF-8 sequences for which a shorter encoding exists. |
|
4.1 Examples of an overlong ASCII character |
|
With a safe UTF-8 decoder, all of the following five overlong |
representations of the ASCII character slash ("/") should be rejected |
like a malformed UTF-8 sequence, for instance by substituting it with |
a replacement character. If you see a slash below, you do not have a |
safe UTF-8 decoder! |
|
4.1.1 U+002F = c0 af = "À¯" |
4.1.2 U+002F = e0 80 af = "à€¯" |
4.1.3 U+002F = f0 80 80 af = "ð€€¯" |
4.1.4 U+002F = f8 80 80 80 af = "ø€€€¯" |
4.1.5 U+002F = fc 80 80 80 80 af = "ü€€€€¯" |
|
4.2 Maximum overlong sequences |
|
Below you see the highest Unicode value that is still resulting in an |
overlong sequence if represented with the given number of bytes. This |
is a boundary test for safe UTF-8 decoders. All five characters should |
be rejected like malformed UTF-8 sequences. |
|
4.2.1 U-0000007F = c1 bf = "Á¿" |
4.2.2 U-000007FF = e0 9f bf = "àŸ¿" |
4.2.3 U-0000FFFF = f0 8f bf bf = "ð<>¿¿" |
4.2.4 U-001FFFFF = f8 87 bf bf bf = "ø‡¿¿¿" |
4.2.5 U-03FFFFFF = fc 83 bf bf bf bf = "üƒ¿¿¿¿" |
|
4.3 Overlong representation of the NUL character |
|
The following five sequences should also be rejected like malformed |
UTF-8 sequences and should not be treated like the ASCII NUL |
character. |
|
4.3.1 U+0000 = c0 80 = "À€" |
4.3.2 U+0000 = e0 80 80 = "à€€" |
4.3.3 U+0000 = f0 80 80 80 = "ð€€€" |
4.3.4 U+0000 = f8 80 80 80 80 = "ø€€€€" |
4.3.5 U+0000 = fc 80 80 80 80 80 = "ü€€€€€" |
|
5 Illegal code positions |
|
The following UTF-8 sequences should be rejected like malformed |
sequences, because they never represent valid ISO 10646 characters and |
a UTF-8 decoder that accepts them might introduce security problems |
comparable to overlong UTF-8 sequences. |
|
5.1 Single UTF-16 surrogates |
|
5.1.1 U+D800 = ed a0 80 = "í €" |
5.1.2 U+DB7F = ed ad bf = "í­¿" |
5.1.3 U+DB80 = ed ae 80 = "í®€" |
5.1.4 U+DBFF = ed af bf = "í¯¿" |
5.1.5 U+DC00 = ed b0 80 = "í°€" |
5.1.6 U+DF80 = ed be 80 = "í¾€" |
5.1.7 U+DFFF = ed bf bf = "í¿¿" |
|
5.2 Paired UTF-16 surrogates |
|
5.2.1 U+D800 U+DC00 = ed a0 80 ed b0 80 = "𐀀" |
5.2.2 U+D800 U+DFFF = ed a0 80 ed bf bf = "𐏿" |
5.2.3 U+DB7F U+DC00 = ed ad bf ed b0 80 = "í­¿í°€" |
5.2.4 U+DB7F U+DFFF = ed ad bf ed bf bf = "í­¿í¿¿" |
5.2.5 U+DB80 U+DC00 = ed ae 80 ed b0 80 = "󰀀" |
5.2.6 U+DB80 U+DFFF = ed ae 80 ed bf bf = "󰏿" |
5.2.7 U+DBFF U+DC00 = ed af bf ed b0 80 = "􏰀" |
5.2.8 U+DBFF U+DFFF = ed af bf ed bf bf = "􏿿" |
|
5.3 Other illegal code positions |
|
5.3.1 U+FFFE = ef bf be = "￾" |
5.3.2 U+FFFF = ef bf bf = "ï¿¿" |
|
THE END |

BIN
ws2010/gdi3/p5/lib/libSDL.a Normal file

Binary file not shown.

View File

@ -0,0 +1,41 @@
# libSDL.la - a libtool library file
# Generated by ltmain.sh (GNU libtool) 2.2.6
#
# Please DO NOT delete this file!
# It is necessary for linking the library.
# The name that we can dlopen(3).
dlname='libSDL-1.2.so.0'
# Names of this library.
library_names='libSDL-1.2.so.0.11.3 libSDL-1.2.so.0 libSDL.so'
# The name of the static archive.
old_library='libSDL.a'
# Linker flags that can not go in dependency_libs.
inherited_linker_flags=''
# Libraries that this one depends upon.
dependency_libs=' -lm -ldl -lpthread'
# Names of additional weak libraries provided by this library
weak_library_names=''
# Version information for libSDL.
current=11
age=11
revision=3
# Is this an already installed library?
installed=yes
# Should we warn about portability when linking against -modules?
shouldnotlink=no
# Files to dlopen/dlpreopen
dlopen=''
dlpreopen=''
# Directory that this library needs to be installed in:
libdir='/usr/lib'

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,79 @@
#include <stdlib.h>
#include <stdio.h>
using namespace std;
#include "MandelbrotSimple.class.h"
#include "MandelbrotOMP.class.h"
#include "MandelbrotPOSIX.class.h"
#include "Painter.class.cpp"
//#include <pthread.h> // POSIX-threads
static const int ASCII_WIDTH = 50;
static const int ASCII_HEIGHT = 35;
static const int PIXEL_WIDTH = 1024;
static const int PIXEL_HEIGHT = 768;
/*
* check arguments, create all necessary objects
*/
int main(int argc, char *argv[])
{
if (argc<6)
{
printf("wrong number of arguments:\n1. number of iterations\n2. output mode [0 = disabled; 1 = ASCII; 2 = Graphic]\n3. OpenMP -> Number of threads\n4. Multithreading [0 = POSIX-Threads; 1 = OpenMP]\n5. SSE [0 = No SSE; 1 = SSE]\n");
return -1;
}
int i_iterations = atoi(argv[1]); //how many iterations
int i_outtype = atoi(argv[2]); //how 2 print
int i_threads = atoi(argv[3]);
int i_posix = atoi(argv[4]);
int i__sse = atoi(argv[5]);
bool i_sse = false;
if(i__sse == 1){
i_sse = true;
}
//Define size
int x_width = 0;
int y_height = 0;
switch(i_outtype){
case 1:
x_width = ASCII_WIDTH;
y_height = ASCII_HEIGHT;
break;
case 2:
x_width = PIXEL_WIDTH;
y_height = PIXEL_HEIGHT;
break;
default:
break;
}
//create Mandelbrot Obj.
IMandelbrot* mandelbrot;
if(i_threads <= 1){
mandelbrot = new CMandelbrotSimple(x_width, y_height, i_iterations, i_threads, i_sse);
} else {
if(i_posix == 1) {
mandelbrot = new CMandelbrotOMP(x_width, y_height, i_iterations, i_threads, i_sse);
} else {
mandelbrot = new CMandelbrotPOSIX(x_width, y_height, i_iterations, i_threads, i_sse);
}
}
//Calculate stuff
mandelbrot->calculateMandelbrot();
//Printstuff
CPainter::print(i_outtype, mandelbrot->getOutArray(), x_width, y_height);
delete mandelbrot;
return 0;
}

View File

@ -0,0 +1,95 @@
/*
* posix_threads.cpp
*
* Created on: 10.01.2011
* Author: mk
*/
#include <pthread.h> // POSIX-threads
#include <time.h> // time operations (to calculate the runtime)
#include <stdio.h> // standard IO operations (to print to console)
#include <stdlib.h> // general purpose standard library (to generate random numbers)
#define NUM_ELEMENTS 1000000 // number of array-elements to add
pthread_t* threads; // stores the posix-thread-objects
int* threadNums; // stores the thread-numbers
time_t beginCalc,endCalc; // used to calculate the runtime of the program
unsigned long a[NUM_ELEMENTS],b[NUM_ELEMENTS],c[NUM_ELEMENTS]; // arrays to add (c=a+b)
int numThreads; // number of threads to create
/*
* fills the arrays with random numbers between 0 and 9
*/
void fillArrays()
{
for(unsigned i=0;i<NUM_ELEMENTS;i++)
{
a[i] = rand() % 10;
b[i] = rand() % 10;
}
}
/*
* this function is called after a thread has been created by pthread_create
*/
void* addArrays(void* pThreadNum)
{
int* threadNum = (int*)pThreadNum;
printf("Thread %i started\n",*threadNum);
unsigned begin,end; // stores the first and last array index which this thread calculates
if(*threadNum == -1) // only one thread, so no POSIX-threads to create
{
begin = 0;
end = NUM_ELEMENTS;
}
else // calculate the first and last array index this thread has to calculate
{
begin = (NUM_ELEMENTS/numThreads)**threadNum;
end = (NUM_ELEMENTS/numThreads)*(*threadNum+1);
}
for (unsigned j=0;j<10000;j++) // run 10.000 times to get a runtime long enough to compare
for (unsigned i=begin;i<end;i++)
c[i] = a[i] + b[i]; // add array elements
}
int main(int argc, char* argv[])
{
if(argc!=2)
{
printf("error! first parameter should be: number of threads\n");
return -1;
}
numThreads = atoi(argv[1]); // get number of threads from the first parameter
fillArrays(); // fill the arrays with random numbers
time(&beginCalc); // store the time at the beginning of the calculation
if(numThreads==1) // no POSIX-threads need to be created
{
int noThreads = -1;
addArrays((void*)&noThreads);
}
else if(numThreads>1)
{
threads = (pthread_t*)malloc(numThreads*sizeof(pthread_t)); // reserve memory for the threads
threadNums = (int*)malloc(numThreads*sizeof(int)); // reserve memory for the thread-numbers
for (unsigned i=0;i<numThreads;i++)
{
threadNums[i] = i;
pthread_create(&threads[i],NULL,addArrays,(void *)&threadNums[i]); // create thread
}
// wait for termination of all threads
for(unsigned i=0;i<numThreads;i++)
pthread_join(threads[i],NULL);
// free memory
free(threads);
free(threadNums);
}
else
{
printf("error! number of threads must be positive\n");
return -1;
}
time(&endCalc); // store the time at the end of the calculation
double timePassed = difftime(endCalc,beginCalc); // calculate the passed time between beginning and end of the calculation
printf("%f seconds passed\n",timePassed);
return 0;
}

3
ws2010/gdi3/p5/run.sh Normal file
View File

@ -0,0 +1,3 @@
#!/bin/bash
g++ -Llib -lSDLmain -lSDL -lSDL_ttf -pthread -fopenmp -msse2 -O1 ./mandelbrot_vorgabe.cpp -o ./mandelbrot

BIN
ws2010/gdi3/p5/solution.odt Normal file

Binary file not shown.

BIN
ws2010/gdi3/p5/solution.pdf Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
ws2010/gdi3/u1/solution.odt Normal file

Binary file not shown.

BIN
ws2010/gdi3/u1/solution.pdf Normal file

Binary file not shown.

72
ws2010/gdi3/u1/u01.txt Normal file
View File

@ -0,0 +1,72 @@
.data
a:.long 12
b:.long 3
c:.long 2
d:.long 12
e:.long 12
.text
movl a,%eax 8T
movl b,%ebx 8T
movl d,%ecx 8T
addl $2,%eax 4T
addl $1,%ebx 4T
addl e,%ecx 9T
div c 159T = 200T #ok
Registerinhalte:
%eax = (a + 2) = 14/2 = 7
%ebx = b + 1 = 4
%ecx = d + e = 24
###OK
.data
a:.long 12
b:.long 3
c:.long 2
d:.long 12
e:.long 12
.text
movl a,%eax 8T
movl b,%ebx 8T
movl d,%ecx 8T
movl e,%edx 8T
addl $2,%eax 4T
incl %ebx 3T
addl %edx,%ecx 3T
shrl $1,%eax 2T = 44T #ok
Registerinhalte:
%eax = (a + 2) << 1 = 14 << 1 = 01110b << 1 = 11100b = 28
%ebx = b + 1 = 4
%ecx = d + e = 24
%edx = e = 12
###??? %eax !
Aufgabe C: Shiften! #ok
Aufgabe 2: #UNTERSCHIEDE, ABER GLEICHES PRINZIP
%eax << 4bit zahl >> %eax (5bit zahl)
movl %eax, %ebx # zahl kopieren
movl $0, %ecx # c = 0
andl 1000b, %ebx # b = 1 oder 0
addl %ebx, %ecx # c += b
movl %eax, %ebx # zahl kopieren
and 0100b, %ebx # b = 1 oder 0
addl %ebx, %ecx # c += b
and 0010b, %ebx # b = 1 oder 0
addl %ebx, %ecx # c += b
and 0001b, %ebx # b = 1 oder 0
addl %ebx, %ecx # c += b
and 0001b , %ecx #counter ungerade?
shrl $1, %eax #shifte zahl um 1
or %ecx, %eax #falls counter ungerade war setze 1 and 1. stelle.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

39
ws2010/gdi3/u11/a1.txt Normal file
View File

@ -0,0 +1,39 @@
FORKS: SEMAPHORE[] = {1,1,1,1,1} // Verfügbare Gabeln
PSTATUS: INTEGER[] = {0,0,0,0,0} // 0 = Denken, 1 = Hungrig, 2=Essend
philosoph i=[0,3] : PROCESS; // Philosoph 0-3
BEGIN
IF PSTATUS[i] == 1 //Hat Hunger - Philosoph muss sich selber auf hungrig setzen
BEGIN
P(FORKS[(i+4) mod 5])
P(FORKS[i])
PSTATUS[i] = 2; //Isst
WHILE(PSTATUS[i] == 2) //Philosoph muss sich selber auf denkend setzen
BEGIN
END
V(FORKS[(i+4) mod 5])
V(FORKS[i])
END
END
philosoph i=4 : PROCESS; // Philosoph 4
BEGIN
IF PSTATUS[i] == 1 //Hat Hunger - Philosoph muss sich selber auf hungrig setzen
BEGIN
P(FORKS[i]) //Reservierung erfolgt in umgekehrter Reihenfolge!
P(FORKS[(i+4) mod 5])
PSTATUS[i] = 2; //Isst
WHILE(PSTATUS[i] == 2) //Philosoph muss sich selber auf denkend setzen
BEGIN
END
V(FORKS[i])
V(FORKS[(i+4) mod 5])
END
END

BIN
ws2010/gdi3/u11/a1a.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

BIN
ws2010/gdi3/u11/a1a.vsd Normal file

Binary file not shown.

BIN
ws2010/gdi3/u11/a2.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

BIN
ws2010/gdi3/u11/a2.vsd Normal file

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,187 @@
import java.lang.Math;
import java.math.BigInteger;
import java.util.Random;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class RSA {
final static BigInteger m =
new BigInteger("91011121314151617181920212223242526272829",10);
BigInteger p = new BigInteger("0",10);
BigInteger q = new BigInteger("0",10);
BigInteger phi = new BigInteger("0",10);
BigInteger e = new BigInteger("0",10);
BigInteger sha = new BigInteger("0",10);
BigInteger n = new BigInteger("0",10);
BigInteger d = new BigInteger("0",10);
BigInteger encrypted = new BigInteger("0",10);
BigInteger decrypted = new BigInteger("0",10);
//Generates a PrimNumber
private BigInteger genPrim(int bitlen){
BigInteger p = BigInteger.probablePrime(bitlen, new Random());
if(!p.isProbablePrime(100000)){
throw new RuntimeException();
}
return p;
}
//Generates an E using phi
private void genE(BigInteger phi){
e = genPrim(256);
if(!phi.gcd(e).equals(BigInteger.ONE)){
genE(phi);
}
}
//Encrypt-Funktion
public void encrypt(){
q = genPrim(256); //get q
p = genPrim(256); //get p
if(p.equals(q)){ //ensure p!=q
encrypt();
}
phi = p.subtract(BigInteger.ONE).multiply(
q.subtract(BigInteger.ONE)); //phi=(p - 1)(q - 1)
n = p.multiply(q); //n = p*q
genE(phi); //get e
SHA256(); //calculate Hash of m
encrypted = expModuloN(sha, e, n); // hash^e mod n
}
//Decrypt Function (you need 2 run encrypt first)
public void decrypt(){
d = extEuklid(e, phi); //calculate d
decrypted = expModuloN(encrypted, d, n); //decrypt
}
//extended Euklid-Algorithm
private BigInteger extEuklid(BigInteger a, BigInteger b){
//Ancor
if(b.equals(BigInteger.ZERO)){
return BigInteger.ONE;
}
//Initialize vars
BigInteger x1 = new BigInteger("0",10);
BigInteger x2 = new BigInteger("1",10);
BigInteger y = new BigInteger("1",10);
BigInteger y1 = new BigInteger("1",10);
BigInteger y2 = new BigInteger("0",10);
BigInteger r = new BigInteger("0",10);
BigInteger q = new BigInteger("0",10);
BigInteger x = new BigInteger("0",10);
while(b.compareTo(BigInteger.ZERO) == 1){
q = a.divide(b);
r = a.mod(b);
x = x2.subtract(q.multiply(x1));
y = y2.subtract(q.multiply(y1));
a = b;
b = r;
x2 = x1;
x1 = x;
y2 = y1;
y1 = y;
}
if(x2.compareTo(BigInteger.ZERO) == -1){
x2 = phi.add(x2);
}
return x2; //only x2 is needed
}
//Efficient m^e mod n
private BigInteger expModuloN(BigInteger m, BigInteger e, BigInteger n){
BigInteger b = m;
BigInteger r = BigInteger.ONE;
for(int i = 0; i <= e.bitLength(); i++){
if(e.testBit(i)){
r = r.multiply(b).mod(n);
}
b = b.multiply(b).mod(n);
}
return r;
}
//Converts a byte to a HexString
public String BytetoHex(byte b) {
int value = (b & 0x7F) + (b < 0 ? 128 : 0);
String ret = (value < 16 ? "0" : "");
ret += Integer.toHexString(value).toUpperCase();
return ret;
}
//Converts SHA-byte-array to HexString
public String SHAtoHex(byte[] d)
{
StringBuffer buf = new StringBuffer();
for (int i = 0; i < d.length; i++) {
buf.append(BytetoHex(d[i]));
}
return buf.toString();
}
//Calculates SHA256 of m
private void SHA256(){
try {
MessageDigest l = MessageDigest.getInstance("SHA-256");
l.reset();
l.update(m.toByteArray());
sha = new BigInteger(SHAtoHex(l.digest()), 16);
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException();
}
}
public static void main(String[] args) {
RSA r = new RSA();
r.encrypt(); //calculate all
r.decrypt();
//Print all
System.out.println("\nKey public:");
System.out.println("\t e: " + r.e);
System.out.println("\t n: " + r.n);
System.out.println("\nKey private:");
System.out.println("\t d: " + r.d);
System.out.println("\nHashvalue:");
System.out.println("\t sha: " + r.sha);
System.out.println("\nSignature:");
System.out.println("\t Enc.: " + r.encrypted);
System.out.println("\nDecrypted:");
System.out.println("\t Dec.: " + r.decrypted);
System.out.println("\nSHA = Decrypted:");
System.out.println(r.decrypted.equals(r.sha));
}
}

BIN
ws2010/ts/Hausuebung/a3.JPG Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 MiB

BIN
ws2010/ts/Hausuebung/a4.JPG Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

BIN
ws2010/ts/Hausuebung/a5.JPG Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 MiB

Binary file not shown.

View File

@ -0,0 +1,11 @@
Klausur Infos:
Mitteilung vom Assistent in der letzten Vorlesung:
- 1 Aufgabe: Multiply Choice aus allen Gebieten
- RSA, RSA-Signatur (erweiterter euklidischer Algorithmus), schnelle Exponentation
- El-Gamal (was ist diskreter Algorithmus? usw.)
- Authentifikationsprotokolle (Bsp. Hausübung)
- Exit-Louroll.? (Bell-La Padula)
- zuverlässige Systeme
- letzten beiden Foliensätze (Testen, Verifizieren) -> aktuelle Übung

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB