/* XTrkCad - Model Railroad CAD * Copyright (C) 2005 Dave Bullis * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include typedef struct { int w; int h; char * b; } bitmap_t; #define RGB(R,G,B) (((R)<<16)|((G)<<8)|(B)) static struct { long rgb; int key; } mainColorMap[256]; static int mainColorCnt; static int fileColorMap[256]; static int sizeColorMap( void ) { return mainColorCnt; } static void printColorMap( FILE * fout ) { int inx, r, g, b; long rgb; for ( inx=0; inx>16)&0xFF; g = (rgb>>8)&0xFF; b = (rgb)&0xFF; fprintf( fout, "\"%c\tc #%2.2X%s%2.2X%s%2.2X%s\",\n", mainColorMap[inx].key, r, ((r&1)?"FF":"00"), g, ((g&1)?"FF":"00"), b, ((b&1)?"FF":"00") ); } } static int allocColor( long color ) { int inx; for ( inx=0; inx= 256 ) { fprintf( stderr, "too many colors\n" ); exit(1); } mainColorMap[mainColorCnt].rgb = color; mainColorMap[mainColorCnt].key = mainColorCnt+'0'; return mainColorMap[mainColorCnt++].key; } static void resetColor( void ) { int inx; for ( inx=0; inx<256; inx++ ) fileColorMap[inx] = -1; } static void mapColor( int inx, long rgb ) { fileColorMap[inx] = allocColor(rgb); } static int remapColor( int oldColor ) { int newColor; newColor = fileColorMap[oldColor]; if ( newColor < 0 ) { fprintf( stderr, "unknown color inx: %d\n", oldColor ); return ' '; } return newColor; } static int read_xpm( char * filename, int *rw, int *rh, int bx, int by, bitmap_t *bm ) { char line[1024], *cp, *cq, *buffer, color[5]; FILE * f; int numcol, curcol, depth, linenum; int col, row, len, r, g, b; long rgb; f = fopen( filename, "r" ); if ( !f ) { perror( filename ); return 0; } numcol = -1; curcol = 0; linenum = 0; resetColor(); row = by; while (fgets( line, sizeof line, f ) ) { linenum++; if ( line[0] != '"' ) continue; if ( numcol == -1 ) { if ( sscanf( line+1, "%d%d%d%d", rw, rh, &numcol, &depth ) != 4 ) { fprintf( stderr, "bogus XPM header: %s:%d\n", filename, linenum ); return 0; } if (!bm) return 1; } else if ( curcol < numcol ) { if ( strncmp( line+2, "\tc #", 4 ) != 0 ) { fprintf( stderr, "bogus XPM color line: %s:%d\n", filename, linenum ); return 0; } color[3] = 0; memcpy( color, line+6, 2 ); r = strtol( color, &cp, 16 ); memcpy( color, line+10, 2 ); g = strtol( color, &cp, 16 ); memcpy( color, line+14, 2 ); b = strtol( color, &cp, 16 ); rgb = RGB(r,g,b); if ( curcol == 0 ) fileColorMap[line[1]] = '0'; else mapColor( line[1], rgb ); curcol++; } else { if ( row > by+*rh ) { fprintf( stderr, "too many data lines: %s:%d\n", filename, linenum ); return 0; } if ( row > bm->h ) return 1; cp = line+1; for ( col=0; col<*rw; col++,cp++ ) { if ( bx+col > bm->w ) break; if ( *cp == '"' ) { fprintf( stderr, "short data line: %s:%d\n", filename, linenum ); return 0; } bm->b[bx+col+bm->w*row] = remapColor( *cp ); } row++; } } fclose( f ); return 1; } static void drawVline( bitmap_t * bm, int col, int x, int y0, int y1 ) { int jj; if ( x > bm->w ) return; for ( jj=y0; jj<=y1; jj++ ) { if ( jj>=bm->h ) return; bm->b[jj*bm->w+x] = col; } } static void drawHline( bitmap_t * bm, int col, int x0, int x1, int y ) { int ii; if ( y > bm->h ) return; for ( ii=x0; ii<=x1; ii++ ) { if ( ii>=bm->w ) return; bm->b[y*bm->w+ii] = col; } } static void fillBlock( bitmap_t * bm, int col, int x, int y, int w, int h ) { int ii, jj; for ( jj=y; jjbm->h ) return; for ( ii=x; iibm->w ) return; bm->b[jj*bm->w+ii] = col; } } } int main ( int argc, char * argv[] ) { char * name; int colWhite, colMdGray, colDkGray, colBlack; int bx, w, h; bitmap_t bm; char ** filename; int ii, jj; char * cp; int argn; if ( argc < 3 ) { fprintf( stderr, "usage: %s NAME FILE1.XPM...\n", argv[0] ); exit(1); } colMdGray = allocColor( RGB(0xC0,0xC0,0xC0) ); colWhite = allocColor( RGB(255,255,255) ); colDkGray = allocColor( RGB(0x80,0x80,0x80) ); colBlack = allocColor( RGB(0,0,0) ); allocColor( RGB(255,0,0) ); name = argv[1]; argc -= 2; filename = &argv[2]; bm.w = 1; bm.h = 0; for ( argn=0; argn bm.h ) bm.h = h+10; bm.w += w+9; } bm.b = (char*)malloc( bm.w*bm.h ); memset( bm.b, 0, bm.w*bm.h ); fillBlock( &bm, colMdGray, 0, 0, bm.w, bm.h ); bx = 0; for ( argn=0; argn