1 // gcc -Wall -g bmp2dat.c -o bmp2dat `sdl-config --cflags --libs`
2
3 #include <stdlib.h>
4 #include <stdio.h>
5 #include <stdint.h>
6 #include <limits.h>
7 #include <errno.h>
8 #include <string.h>
9
10 #include <SDL.h>
11
12 #define IMAGE_DAT_OR_MASK 0xff030303 // Reduce colour depth of images slightly for better compression (and remove useless top 8 bits!)
13
14 #define ERROR_PRINTF(...) { fprintf(stderr, "%s:%s:%u Error: ", __FILE__, __PRETTY_FUNCTION__, __LINE__); fprintf(stderr,__VA_ARGS__); fflush(stderr); }
15
Peek(SDL_Surface * i,int x,int y)16 static int Peek(SDL_Surface* i, int x, int y)
17 {
18 if (x<0 || y<0 || x>=i->w || y>=i->h)
19 return 0;
20 unsigned int p=0;
21 const int BytesPerPixel = i->format->BytesPerPixel;
22 const int BitsPerPixel = i->format->BitsPerPixel;
23 if (BitsPerPixel==8)
24 p = ((unsigned char*)i->pixels)[i->pitch*y + x*BytesPerPixel];
25 else if (BitsPerPixel==15 || BitsPerPixel==16)
26 p = *(short*)(((char*)i->pixels) + (i->pitch*y + x*BytesPerPixel));
27 else if (BitsPerPixel==32)
28 p = *(unsigned int*)(((char*)i->pixels) + (i->pitch*y + x*BytesPerPixel));
29 else if (BitsPerPixel==24)
30 p = (int)((unsigned char*)i->pixels)[i->pitch*y + x*BytesPerPixel]
31 | (int)((unsigned char*)i->pixels)[i->pitch*y + x*BytesPerPixel] << 8
32 | (int)((unsigned char*)i->pixels)[i->pitch*y + x*BytesPerPixel] << 16;
33
34 return p;
35 }
36
IsEmpty(SDL_Surface * im,int x,int y,int w,int h)37 static int IsEmpty(SDL_Surface* im, int x, int y, int w, int h)
38 {
39 int i, j;
40 for (i=x; i<x+w; i++)
41 for (j=y; j<y+h; j++)
42 if (Peek(im,i,j) != Peek(im,0,im->h-1))
43 return 0;
44 return 1;
45 }
46
main(int argc,char ** argv)47 int main(int argc, char** argv)
48 {
49 typedef unsigned int uint32;
50 SDL_Surface * g = NULL;
51 const char *bmp = NULL;
52 const char *dat = NULL;
53 int colourKey = 1;
54
55 if (argc < 3)
56 {
57 fprintf(stderr, "Usage: %s file.bmp file.dat\n", argv[0]);
58 return -1;
59 }
60
61 bmp = argv[1];
62 dat = argv[2];
63
64 g = SDL_LoadBMP(bmp);
65
66 // SDL_PixelFormat p;
67 // p.sf = 1;
68 // SDL_Surface* tmp = SDL_ConvertSurface(g, &p, SDL_SWSURFACE);
69
70 short w=g->w, h=g->h;
71 char* buf = (char*) g->pixels;
72 if (colourKey)
73 {
74 while (IsEmpty(g, w-1, 0, 1, h) && w>1)
75 w--;
76 while (IsEmpty(g, 0, h-1, w, 1) && h>1)
77 h--;
78 }
79
80 FILE* f = fopen(dat, "wb");
81 fwrite(&w, sizeof(w), 1, f);
82 fwrite(&h, sizeof(h), 1, f);
83
84 uint32 mask = IMAGE_DAT_OR_MASK;
85 int i;
86 for (i=0; i<(int)w*h; )
87 {
88 uint32 c = (*(uint32*)&buf[(i%w)*3 + (i/w)*g->pitch] | mask);
89 int i0 = i;
90 while (i < (int)w*h && c == (*(uint32*)&buf[(i%w)*3 + (i/w)*g->pitch] | mask))
91 i++;
92 c &= 0xffffff;
93 i0 = i-i0-1;
94 if (i0 < 0xff)
95 c |= i0 << 24;
96 else
97 c |= 0xff000000;
98
99 fwrite(&c, sizeof(c), 1, f);
100
101 if (i0 >= 0xff)
102 fwrite(&i0, sizeof(i0), 1, f);
103 }
104 fclose(f);
105
106 SDL_FreeSurface(g);
107
108 return 0;
109 }
110