summaryrefslogtreecommitdiff
path: root/app/help/fixbmp.c
diff options
context:
space:
mode:
Diffstat (limited to 'app/help/fixbmp.c')
-rw-r--r--app/help/fixbmp.c227
1 files changed, 227 insertions, 0 deletions
diff --git a/app/help/fixbmp.c b/app/help/fixbmp.c
new file mode 100644
index 0000000..44555dc
--- /dev/null
+++ b/app/help/fixbmp.c
@@ -0,0 +1,227 @@
+
+/* 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 <stdio.h>
+
+#define TRUE (1)
+#define FALSE (0)
+
+struct BITMAPFILEHEADER {
+ char bfType[2];
+ long bfSize;
+ short bfRsvd1;
+ short bfRsvd2;
+ long bfOffBits;
+ };
+
+struct BITMAPINFOHEADER {
+ long biSize;
+ long biWidth;
+ long biHeight;
+ short biPlanes;
+ short biBitCount;
+ long biCompression;
+ long biSizeImage;
+ long biXPelsPerMeter;
+ long biYPelsPerMeter;
+ long biClrUsed;
+ long biClrImportant;
+ };
+
+int namenames;
+int dumpInfo;
+int dumpColorMap;
+int dumpBits;
+int dumpHisto;
+int updateColorCount;
+int zeroColorCount;
+int setColorCount;
+int fixColorMap;
+
+int fixbmp( char * filename )
+{
+ FILE * file;
+ struct BITMAPFILEHEADER bmfh;
+ struct BITMAPINFOHEADER bmih;
+ int rc;
+ long colors[256];
+ int i, j, size;
+ unsigned char * bmp, bit;
+ int colorCnt;
+ long maxcolor;
+ long histo[256];;
+
+ if ( namenames )
+ printf( "%s\n", filename );
+ file = fopen( filename, "r+" );
+ if ( file == NULL ) {
+ fprintf( stderr, "%s: Cant open:%s\n", filename, filename );
+ return FALSE;
+ }
+ rc = fread( &bmfh.bfType, 1, sizeof bmfh.bfType, file );
+ rc += fread( &bmfh.bfSize, 1, sizeof bmfh.bfSize, file );
+ rc += fread( &bmfh.bfRsvd1, 1, sizeof bmfh.bfRsvd1, file );
+ rc += fread( &bmfh.bfRsvd2, 1, sizeof bmfh.bfRsvd2, file );
+ rc += fread( &bmfh.bfOffBits, 1, sizeof bmfh.bfOffBits, file );
+ if ( rc != 14 ) {
+ fprintf( stderr, "%s: Bad read of bmfh: %d\n", filename, rc );
+ return FALSE;
+ }
+ rc = fread( &bmih, 1, sizeof bmih, file );
+ if ( rc != sizeof bmih ) {
+ fprintf( stderr, "%s: Bad read of bmih: %d\n", filename, rc );
+ return FALSE;
+ }
+ if ( dumpInfo ) {
+ printf( "fh:sz=%d, off=%ld\n", bmfh.bfSize, bmfh.bfOffBits );
+ printf( "ih:sz=%ld, w=%ld, h=%ld, (%ld), pl=%d, bc=%d, co=%ld, si=%ld, cu=%ld, ci=%ld\n",
+ bmih.biSize, bmih.biWidth, bmih.biHeight, bmih.biWidth*bmih.biHeight,
+ bmih.biPlanes, bmih.biBitCount, bmih.biCompression,
+ bmih.biSizeImage, bmih.biClrUsed, bmih.biClrImportant );
+ }
+ if ( bmih.biPlanes != 1 || bmih.biBitCount != 8 ) {
+ fprintf( stderr, "%s: bad Planes(%d) or BitCount(%d)\n", filename, bmih.biPlanes, bmih.biBitCount );
+ return FALSE;
+ }
+ if ( bmih.biClrUsed > 256 ) {
+ fprintf( stderr, "%s: Too many colors (%ld)\n", filename, bmih.biClrUsed );
+ return FALSE;
+ }
+ colorCnt = bmih.biClrUsed;
+ if ( colorCnt == 0 )
+ colorCnt = 256;
+ rc = fread( colors, sizeof colors[0], colorCnt, file );
+ if ( rc != colorCnt ) {
+ fprintf( stderr, "%s: Bad read of colors: %d\n", filename, rc );
+ return FALSE;
+ }
+ if ( dumpColorMap ) {
+ printf( "colorcnt=%d", rc );
+ for ( i=0; i<colorCnt; i++ ) {
+ if ( i%8 == 0 )
+ printf( "\n%2.2x: ", i );
+ printf( "%8.8lx ", colors[i] );
+ }
+ printf( "\n" );
+ }
+ if ( fixColorMap ) {
+ long c;
+ for ( i=0; i<colorCnt; i++ ) {
+ c = colors[i]&0xFFFFFF;
+ if ( (c & 0xFF0000) != 0xFF0000 )
+ c &= 0xF0FFFF;
+ if ( (c & 0x00FF00) != 0x00FF00 )
+ c &= 0xFFF0FF;
+ if ( (c & 0x0000FF) != 0x0000FF )
+ c &= 0xFFFFF0;
+ colors[i] = c;
+ }
+ fseek( file, 14+40, SEEK_SET );
+ rc = fwrite( colors, sizeof colors[0], colorCnt, file );
+ if ( rc != colorCnt ) {
+ fprintf( stderr, "%s: Bad write of colors: %d\n", filename, rc );
+ return FALSE;
+ }
+ }
+ size = (int)(bmih.biWidth*bmih.biHeight);
+ size = (int)bmih.biWidth;
+ size = (size+3)/4*4;
+ fseek( file, bmfh.bfOffBits, SEEK_SET );
+ bmp = (unsigned char*)malloc( size );
+ if ( bmp == NULL ) {
+ fprintf( stderr, "%s: Cant malloc(%d) for bitmap\n", filename, size );
+ return FALSE;
+ }
+ maxcolor = 0;
+ memset( histo, 0, sizeof histo );
+ for ( j=0; j<bmih.biHeight; j++ ) {
+ rc = fread( bmp, 1, size, file );
+ if ( rc != size ) {
+ fprintf( stderr, "%s: Cant read bits for line %d: %d\n", filename, j, rc );
+ return FALSE;
+ }
+ if ( dumpBits )
+ printf( "%2.2d: ", j );
+ for ( i=0; i<bmih.biWidth; i++ ) {
+ bit = bmp[i];
+ histo[bit]++;
+ if ( dumpBits )
+ printf( "%2.2x", bit );
+ if ( bit > maxcolor )
+ maxcolor = bit;
+ }
+ if ( dumpBits )
+ printf( "\n" );
+ }
+ free( bmp );
+ if ( dumpHisto ) {
+ printf( "maxcolor=%ld\n", maxcolor );
+ for ( i=0; i<256; i++ )
+ if ( histo[i] )
+ printf( "[%2.2x]%8.8x = %ld\n", i, colors[i], histo[i] );
+
+ }
+ if ( updateColorCount || zeroColorCount || setColorCount ) {
+ fseek( file, 14, SEEK_SET );
+ if ( updateColorCount ) {
+ bmih.biClrImportant = maxcolor;
+ } else if ( zeroColorCount ) {
+ bmih.biClrImportant = 0;
+ bmih.biClrUsed = 0;
+ } else {
+ bmih.biClrImportant = 256;
+ bmih.biClrUsed = 256;
+ }
+ rc = fwrite( &bmih, 1, sizeof bmih, file );
+ if ( rc != sizeof bmih ) {
+ fprintf( stderr, "%s: Update failed; %d\n", filename, rc );
+ }
+ }
+ fclose( file );
+ return TRUE;
+}
+
+
+int main( int argc, char * argv[] )
+{
+ while ( argc > 2 && argv[1][0] == '-' ) {
+ switch ( argv[1][1] ) {
+ case 'a': dumpInfo++; dumpColorMap++; dumpBits++; dumpHisto++; break;
+ case 'i': dumpInfo++; break;
+ case 'c': dumpColorMap++; break;
+ case 'b': dumpBits++; break;
+ case 'h': dumpHisto++; break;
+ case 'u': updateColorCount++; break;
+ case 'z': zeroColorCount++; break;
+ case 's': setColorCount++; break;
+ case 'f': fixColorMap++; break;
+ default:
+ fprintf( stderr, "bad option %s\n", argv[1] );
+ }
+ argc--;
+ argv++;
+ }
+ if ( argc > 2 && dumpInfo+dumpColorMap+dumpBits+dumpHisto > 0 )
+ namenames++;
+ while ( argc > 1 ) {
+ fixbmp( argv[1] );
+ argc--;
+ argv++;
+ }
+}