Created
October 16, 2011 16:27
-
-
Save garretraziel/1291105 to your computer and use it in GitHub Desktop.
Jednoduchý prohlížeč bmp. Upload kvůli hledání bugu.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <limits.h> | |
#include <SDL/SDL.h> | |
#include <SDL/SDL_gfxPrimitives.h> | |
#define WIDTH 800 | |
#define HEIGHT 600 | |
#define RED 0xff0000ff | |
#define BMP_TYPE 19778 | |
typedef struct { | |
unsigned short type; | |
unsigned long size; | |
unsigned short reversed1; | |
unsigned short reversed2; | |
unsigned long offsetbits; | |
}__attribute__((packed)) BITMAPFILEHEADER; | |
typedef struct { | |
unsigned long size; | |
unsigned long width; | |
unsigned long height; | |
unsigned short planes; | |
unsigned short bitcount; | |
unsigned long compression; | |
unsigned long sizeimage; | |
long xpelspermeter; | |
long ypelspermeter; | |
unsigned long colorsused; | |
unsigned long colorsimportant; | |
}__attribute__((packed)) BITMAPINFOHEADER; | |
typedef struct { | |
unsigned char blue; | |
unsigned char green; | |
unsigned char red; | |
unsigned char offset; | |
}__attribute__((packed)) SINGLE_PIXEL; | |
void printHelp(char *name); | |
void displayWarning(SDL_Surface *screen); | |
int main(int argc, char *argv[]) | |
{ | |
if (argc != 2) { | |
printHelp(argv[0]); | |
return 1; | |
} | |
if (SDL_Init(SDL_INIT_VIDEO) < 0) { | |
fprintf(stderr, "Error: cannot load SDL: %s\n", SDL_GetError()); | |
return 1; | |
} | |
atexit(SDL_Quit); | |
int good_picture = 0; | |
unsigned int width = WIDTH, height = HEIGHT; | |
int pixels_per_color = 0; | |
int colors = 16; | |
int compression = 0; | |
unsigned long size = 0; | |
unsigned long numColors; | |
BITMAPFILEHEADER bmfh; | |
BITMAPINFOHEADER bmih; | |
SINGLE_PIXEL *cplt; | |
unsigned char *pixels; | |
FILE* picture = fopen(argv[1],"rb"); | |
if (picture != NULL) { | |
if (fread(&bmfh,sizeof(BITMAPFILEHEADER),1,picture) == 1) { | |
if (bmfh.type == BMP_TYPE) { | |
if (fread(&bmih,sizeof(BITMAPINFOHEADER),1,picture) == 1) { | |
width = bmih.width; | |
height = bmih.height; | |
pixels_per_color = bmih.bitcount; | |
compression = bmih.compression; | |
printf("width: %d\n",width); | |
printf("height: %d\n",height); | |
printf("bitcount: %d\n",pixels_per_color); | |
if (pixels_per_color < 24) { | |
numColors = 1 << pixels_per_color; | |
printf("numColors: %lu\n",numColors); | |
if (pixels_per_color == 8) { | |
cplt = malloc(sizeof(SINGLE_PIXEL)*numColors); | |
if (cplt == NULL) { | |
fprintf(stderr,"Error: can't allocate memory.\n"); | |
fclose(picture); | |
return 1; | |
} | |
if (numColors != fread(cplt,sizeof(SINGLE_PIXEL),numColors,picture)) { | |
fprintf(stderr,"Error: can't read color palette.\n"); | |
fclose(picture); | |
free(cplt); | |
return 1; | |
} | |
} | |
} | |
size = bmfh.size - bmfh.offsetbits; | |
printf("Size of image: %lu\n",size); | |
pixels = malloc(size*sizeof(unsigned char)); | |
if (pixels == NULL) { | |
fprintf(stderr, "Error: can't allocate memory.\n"); | |
free(cplt); | |
fclose(picture); | |
return 1; | |
} | |
if (size != fread(pixels,sizeof(unsigned char),size,picture)) { | |
fprintf(stderr,"Error: can't read input file.\n"); | |
free(cplt); | |
free(pixels); | |
fclose(picture); | |
return 1; | |
} | |
good_picture = 1; | |
} | |
} | |
} | |
fclose(picture); | |
} | |
unsigned int nejbliz_nas = width; | |
while (nejbliz_nas % 4) nejbliz_nas++; | |
printf("nejbliz: %d\n",nejbliz_nas); | |
SDL_Surface *screen = SDL_SetVideoMode(width,height,colors,SDL_HWSURFACE|SDL_DOUBLEBUF); | |
int done = 1; | |
int barva = 0; | |
int invertovat = 0; | |
while (done) { | |
SDL_Event event; | |
while (SDL_PollEvent(&event)) { | |
switch (event.type) { | |
case SDL_QUIT: | |
done = 0; | |
break; | |
case SDL_KEYDOWN: | |
if (event.key.keysym.sym == SDLK_ESCAPE) | |
done = 0; | |
if (event.key.keysym.sym == SDLK_UP) | |
barva += 5; | |
if (event.key.keysym.sym == SDLK_DOWN) | |
barva -= 5; | |
if (event.key.keysym.sym == SDLK_i) { | |
if (invertovat) invertovat = 0; | |
else invertovat = 1; | |
} | |
break; | |
} | |
} | |
if (!good_picture) { | |
displayWarning(screen); | |
} else { | |
for (unsigned int i = 0; i<size; i++) { | |
if ((i%nejbliz_nas) >= width) { | |
continue; | |
} | |
int pix_r = cplt[pixels[i]].red; | |
int pix_g = cplt[pixels[i]].green; | |
int pix_b = cplt[pixels[i]].blue; | |
if ((pix_r + barva) < 0) pix_r = 0; | |
else if ((pix_r + barva) > 0xff) pix_r = 0xff; | |
else pix_r = pix_r + barva; | |
if ((pix_g + barva) < 0) pix_g = 0; | |
else if ((pix_g + barva) > 0xff) pix_g = 0xff; | |
else pix_g = pix_g + barva; | |
if ((pix_b + barva) < 0) pix_b = 0; | |
else if ((pix_b + barva) > 0xff) pix_b = 0xff; | |
else pix_b = pix_b + barva; | |
if (invertovat) { | |
pix_r = 0xff - pix_r; | |
pix_g = 0xff - pix_g; | |
pix_b = 0xff - pix_b; | |
} | |
unsigned int clr = pix_r*0x1000000 + pix_g*0x10000 + pix_b*0x100 + 0xff; | |
pixelColor(screen,i%nejbliz_nas,height-i/height-1,clr); | |
} | |
/* for (int j=0; j<width; j++) { */ | |
/* for (unsigned int i=0; i<numColors; i++) { */ | |
/* unsigned int clr = cplt[i].red*0x1000000 + cplt[i].green*0x10000 + cplt[i].blue*0x100 + 0xff; */ | |
/* pixelColor(screen,2*i,j,clr); */ | |
/* pixelColor(screen,2*i+1,j,clr); */ | |
/* } */ | |
/* } */ | |
SDL_Flip(screen); | |
} | |
SDL_Delay(10); | |
} | |
if (pixels != NULL) free(pixels); | |
if (cplt != NULL) free(cplt); | |
return 0; | |
} | |
void printHelp(char *name) | |
{ | |
printf("bmpview\n\nusage:\n"); | |
printf("%s file\nwhere: file is input *.bmp file\n",name); | |
} | |
void displayWarning(SDL_Surface *screen) | |
{ | |
stringColor(screen, 5, 5, "Error: cannot read or file doesn't exist.", RED); | |
SDL_UpdateRect(screen, 0,0,0,0); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment