Skip to content

Instantly share code, notes, and snippets.

@garretraziel
Created October 16, 2011 16:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save garretraziel/1291105 to your computer and use it in GitHub Desktop.
Save garretraziel/1291105 to your computer and use it in GitHub Desktop.
Jednoduchý prohlížeč bmp. Upload kvůli hledání bugu.
#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