Skip to content

Commit

Permalink
Moved the code to create a bitmap from a XPM into bmp.c itself (`bm_f…
Browse files Browse the repository at this point in the history
…rom_Xpm()`)

Also renamed bm_fromXbm() to bm_from_Xbm()
  • Loading branch information
wernsey committed Mar 15, 2017
1 parent f1ce528 commit 66a2570
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 74 deletions.
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ Features:
dependencies.
* PNG through [libpng](http://www.libpng.org)
* JPEG through [libjpeg](http://www.ijg.org/)
* `Bitmap` structures can also be created from XBM data.
* Support fo SDL2' `SDL_RWops` file manipulation routines for loading images in
the supported formats.
* Supports manipulation of OpenGL textures, [SDL](https://www.libsdl.org/) surfaces,
Expand All @@ -20,9 +19,11 @@ Features:
* Floodfill and filled primitives
* Image resizing: nearest neighbour, bilinear and bicubic
* Blitting, blitting with masks and scaled blitting.
* Text rendering: built-in 8-bit style raster fonts and FreeType support.
* Text rendering: built-in _8-bit_ style raster fonts and FreeType support.
* Filtering with kernels and smoothing.
* [CSS-style](http://en.wikipedia.org/wiki/Web_colors) colors.
* Loading images from [XBM](https://en.wikipedia.org/wiki/X_BitMap) and
[X PixMap](https://en.wikipedia.org/wiki/X_PixMap) data.
* Cross platform. It's been known to compile under Windows (MinGW), Linux,
Android and Web via Emscripten.

Expand Down
69 changes: 61 additions & 8 deletions bmp.c
Original file line number Diff line number Diff line change
Expand Up @@ -2480,7 +2480,7 @@ void bm_set(Bitmap *b, int x, int y, unsigned int c) {
*p = c;
}

Bitmap *bm_fromXbm(int w, int h, unsigned char *data) {
Bitmap *bm_from_Xbm(int w, int h, unsigned char *data) {
int x,y;

Bitmap *bmp = bm_create(w, h);
Expand All @@ -2498,6 +2498,59 @@ Bitmap *bm_fromXbm(int w, int h, unsigned char *data) {
return bmp;
}

Bitmap *bm_from_Xpm(char *xpm[]) {
#define XPM_MAX_COLORS 256
#define XPM_TRANS_COLOR 1
Bitmap *b;
int w, h, nc, cp;
int i, j, r;
unsigned int colors[XPM_MAX_COLORS];
unsigned char chars[XPM_MAX_COLORS];

r = sscanf(xpm[0], "%d %d %d %d", &w, &h, &nc, &cp);
assert(r == 4);(void)r;
assert(w > 0 && h > 0);
assert(nc > 0 && nc < XPM_MAX_COLORS);
assert(cp == 1); /* cp != 1 not supported */

b = bm_create(w, h);
for(i = 0; i < nc; i++) {
char k, col[20];
col[sizeof col - 1] = 0;
chars[i] = xpm[i+1][0]; /* to allow spaces */
r = sscanf(xpm[i+1] + 1, " %c %s", &k, col);
assert(r == 2);(void)r;
assert(k == 'c'); /* other keys not supported */
assert(col[sizeof col - 1] == 0);
colors[i] = bm_atoi(col);

#ifdef XPM_TRANS_COLOR
for(j=0;col[j];j++){col[j]=tolower(col[j]);}
if(!strcmp(col,"none")){colors[i]=XPM_TRANS_COLOR;}
#endif
}

for(j = 0; j < h; j++) {
char *row = xpm[1 + nc + j];
for(i = 0; i < w; i++) {
assert(row[i]);
for(r = 0; r < nc; r++) {
if(chars[r] == row[i]) {
bm_set_color(b, colors[r]);
break;
}
}
bm_putpixel(b, i, j);
}
}
#ifdef XPM_TRANS_COLOR
bm_set_color(b, XPM_TRANS_COLOR);
#else
bm_set_color(b,1);/* arb color for transparency when saving to GIF */
#endif
return b;
}

void bm_clip(Bitmap *b, int x0, int y0, int x1, int y1) {
if(x0 > x1) {
int t = x1;
Expand Down Expand Up @@ -3971,7 +4024,7 @@ void bm_fill(Bitmap *b, int x, int y) {
unsigned int sc, dc; /* Source and Destination colors */

dc = b->color;
bm_picker(b, x, y);
b->color = BM_GET(b, x, y);
sc = b->color;

/* Don't fill if source == dest
Expand All @@ -3995,17 +4048,17 @@ void bm_fill(Bitmap *b, int x, int y) {
w = n;
e = n;

if(bm_picker(b, n.x, n.y) != sc)
if(BM_GET(b, n.x, n.y) != sc)
continue;

while(w.x > b->clip.x0) {
if(bm_picker(b, w.x-1, w.y) != sc) {
if(BM_GET(b, w.x-1, w.y) != sc) {
break;
}
w.x--;
}
while(e.x < b->clip.x1 - 1) {
if(bm_picker(b, e.x+1, e.y) != sc) {
if(BM_GET(b, e.x+1, e.y) != sc) {
break;
}
e.x++;
Expand All @@ -4014,7 +4067,7 @@ void bm_fill(Bitmap *b, int x, int y) {
assert(i >= 0 && i < b->w);
BM_SET(b, i, w.y, dc);
if(w.y > b->clip.y0) {
if(bm_picker(b, i, w.y - 1) == sc) {
if(BM_GET(b, i, w.y - 1) == sc) {
nn.x = i; nn.y = w.y - 1;
queue[qs++] = nn;
if(qs == mqs) {
Expand All @@ -4026,7 +4079,7 @@ void bm_fill(Bitmap *b, int x, int y) {
}
}
if(w.y < b->clip.y1 - 1) {
if(bm_picker(b, i, w.y + 1) == sc) {
if(BM_GET(b, i, w.y + 1) == sc) {
nn.x = i; nn.y = w.y + 1;
queue[qs++] = nn;
if(qs == mqs) {
Expand Down Expand Up @@ -4141,7 +4194,7 @@ static void reduce_palette_bayer(Bitmap *b, unsigned int palette[], size_t n, in
Floyd-Steinberg, but it does have some advantages:
* the repeating patterns compress better
* it is better suited for line-art graphics
* if you were to make an animation (not supported at the moment)
* if you were to make a limited palette animation (e.g. animated GIF)
subsequent frames would be less jittery than error-diffusion.
*/
int x, y;
Expand Down
24 changes: 16 additions & 8 deletions bmp.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
* * <https://en.wikipedia.org/wiki/Truevision_TGA>
* * <http://paulbourke.net/dataformats/tga/>
* * <http://www.ludorg.net/amnesia/TGA_File_Format_Spec.html>
* * [X PixMap](https://en.wikipedia.org/wiki/X_PixMap)
* * <http://www.fileformat.info/format/xpm/egff.htm>
*
* License
* -------
Expand Down Expand Up @@ -87,7 +89,7 @@ typedef struct bitmap {
* ### Creating and Destroying bitmaps
*/

/** `Bitmap *bm_create(int w, int h)` \
/**`Bitmap *bm_create(int w, int h)` \
* Creates a bitmap of the specified dimensions
*/
Bitmap *bm_create(int w, int h);
Expand All @@ -98,17 +100,23 @@ Bitmap *bm_create(int w, int h);
void bm_free(Bitmap *b);

/** `Bitmap *bm_copy(Bitmap *b)` \
* Creates a duplicate of the bitmap structure.
*
* _Font information is not copied and must be set on the copy before
* text can be drawn on it._
* Creates a duplicate of the bitmap structure `b`.
*/
Bitmap *bm_copy(Bitmap *b);

/** `Bitmap *bm_fromXbm(int w, int h, unsigned char *data)` \
* Creates a `Bitmap` object from XBM data.
/** `Bitmap *bm_from_Xbm(int w, int h, unsigned char *data)` \
* Creates a `Bitmap` object from [XBM data](https://en.wikipedia.org/wiki/X_BitMap). \
* The XBM image is imported into a program through a `#include "include.xbm"` directive. \
* The width `w` and height `h` are the `_width` and `_height` variables at the top of the XBM file.
* The `data` parameter is the `_bits` variable in the XBM file.
*/
Bitmap *bm_from_Xbm(int w, int h, unsigned char *data);

/** `Bitmap *bm_from_Xpm(char *xpm[])` \
* Creates a `Bitmap` object from [X PixMap](https://en.wikipedia.org/wiki/X_PixMap)
* data in a source file.
*/
Bitmap *bm_fromXbm(int w, int h, unsigned char *data);
Bitmap *bm_from_Xpm(char *xpm[]);

/** `int bm_width(Bitmap *b)` \
* Retrieves the width of the bitmap `b`
Expand Down
58 changes: 2 additions & 56 deletions misc/xpm.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,60 +12,6 @@ for error checking.

#include "../bmp.h"

Bitmap *from_xpm3(char *xpm[]) {
#define XPM_MAX_COLORS 256
#define XPM_TRANS_COLOR 1
Bitmap *b;
int w, h, nc, cp;
int i, j, r;
unsigned int colors[XPM_MAX_COLORS];
unsigned char chars[XPM_MAX_COLORS];

r = sscanf(xpm[0], "%d %d %d %d", &w, &h, &nc, &cp);
assert(r == 4);(void)r;
assert(w > 0 && h > 0);
assert(nc > 0 && nc < XPM_MAX_COLORS);
assert(cp == 1); /* cp != 1 not supported */

b = bm_create(w, h);
for(i = 0; i < nc; i++) {
char k, col[20];
col[sizeof col - 1] = 0;
chars[i] = xpm[i+1][0]; /* to allow spaces */
r = sscanf(xpm[i+1] + 1, " %c %s", &k, col);
assert(r == 2);(void)r;
assert(k == 'c'); /* other keys not supported */
assert(col[sizeof col - 1] == 0);
colors[i] = bm_atoi(col);

#ifdef XPM_TRANS_COLOR
for(j=0;col[j];j++){col[j]=tolower(col[j]);}
if(!strcmp(col,"none")){colors[i]=XPM_TRANS_COLOR;}
#endif
}

for(j = 0; j < h; j++) {
char *row = xpm[1 + nc + j];
for(i = 0; i < w; i++) {
assert(row[i]);
for(r = 0; r < nc; r++) {
if(chars[r] == row[i]) {
bm_set_color(b, colors[r]);
break;
}
}
bm_putpixel(b, i, j);
}
}
#ifdef XPM_TRANS_COLOR
bm_set_color(b, XPM_TRANS_COLOR);
#else
bm_set_color(b,1);/* arb color for transparency when saving to GIF */
#endif
return b;
}

#ifdef TEST
/* -- Wikipedia XPM3 examples ----------------------------- */

/* XPM */
Expand Down Expand Up @@ -100,9 +46,9 @@ static char * blarg_xpm[] = {
/* -------------------------------------------------------- */

int main(int argc, char *argv[]) {
Bitmap *b = from_xpm3(blarg_xpm);
Bitmap *b = bm_from_Xpm(blarg_xpm);
bm_save(b, "out.gif");
bm_free(b);
return 1;
}
#endif

0 comments on commit 66a2570

Please sign in to comment.