2 GenSurf plugin for GtkRadiant
3 Copyright (C) 2001 David Hyde, Loki software and qeradiant.com
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 void GenerateBitmapMapping(){
33 unsigned char *colors;
41 for ( j = 0; j <= NV; j++ )
43 y = (double)( j * ( gbmp.height - 1 ) ) / (double)NV;
46 for ( i = 0; i <= NH; i++ )
48 x = (double)( i * ( gbmp.width - 1 ) ) / (double)NH;
51 O00 = r0 * gbmp.width + c0;
52 O01 = r0 * gbmp.width + c1;
53 O10 = r1 * gbmp.width + c0;
54 O11 = r1 * gbmp.width + c1;
55 C0 = (double)colors[O00] + (double)( colors[O01] - colors[O00] ) * ( x - (double)c0 );
56 C1 = (double)colors[O10] + (double)( colors[O11] - colors[O10] ) * ( x - (double)c0 );
57 color = (int)( C0 + ( C1 - C0 ) * ( y - r0 ) );
59 value = CalculateSnapValue( gbmp.black_value + color * ( ( gbmp.white_value - gbmp.black_value ) / 255. ) );
65 xyz[i][j].p[1] = value;
69 xyz[i][j].p[0] = value;
72 xyz[i][j].p[2] = value;
78 static unsigned char* OpenBitmapFile(){
79 #define INVALID_FORMAT do { \
80 fprintf( stderr,"%s:%d: Error file '%s' is malformed.\n",__FILE__,__LINE__,gbmp.name ); \
92 int32_t filesize, pixoff;
93 int32_t bmisize, compression;
94 int32_t xscale, yscale;
95 int32_t colors, impcol;
96 uint32_t m_bytesRead = 0;
100 fp = fopen( gbmp.name, "rb" );
102 fprintf( stderr,"Error: Invalid filename '%s'\n",gbmp.name );
107 rc = fread( &m1, 1, 1, fp );
113 rc = fread( &m2, 1, 1, fp );
115 if ( ( m1 != 'B' ) || ( m2 != 'M' ) ) {
119 rc = fread( (uint32_t*)&( filesize ),4,1,fp ); m_bytesRead += 4;
124 rc = fread( (uint16_t*)&( res1 ),2,1,fp ); m_bytesRead += 2;
129 rc = fread( (uint16_t*)&( res2 ),2,1,fp ); m_bytesRead += 2;
134 rc = fread( (uint32_t*)&( pixoff ),4,1,fp ); m_bytesRead += 4;
139 rc = fread( (uint32_t*)&( bmisize ),4,1,fp ); m_bytesRead += 4;
144 rc = fread( (uint32_t *)&( bmWidth ),4,1,fp ); m_bytesRead += 4;
149 rc = fread( (uint32_t*)&( bmHeight ),4,1,fp ); m_bytesRead += 4;
154 rc = fread( (uint16_t*)&( bmPlanes ),2,1,fp ); m_bytesRead += 2;
159 rc = fread( (uint16_t*)&( bmBitsPixel ),2,1,fp ); m_bytesRead += 2;
164 rc = fread( (uint32_t*)&( compression ),4,1,fp ); m_bytesRead += 4;
169 rc = fread( (uint32_t*)&( sizeimage ),4,1,fp ); m_bytesRead += 4;
174 rc = fread( (uint32_t*)&( xscale ),4,1,fp ); m_bytesRead += 4;
179 rc = fread( (uint32_t*)&( yscale ),4,1,fp ); m_bytesRead += 4;
184 rc = fread( (uint32_t*)&( colors ),4,1,fp ); m_bytesRead += 4;
189 rc = fread( (uint32_t*)&( impcol ),4,1,fp ); m_bytesRead += 4;
194 if ( bmBitsPixel != 8 ) {
195 g_FuncTable.m_pfnMessageBox( g_pWnd, "This is not an 8-bit image. GenSurf can't use it.",
196 "Bitmap", eMB_OK, eMB_ICONWARNING );
202 colors = 1 << bmBitsPixel;
205 if ( bmBitsPixel != 24 ) {
207 for ( i = 0; i < colors; i++ )
209 unsigned char r,g, b, dummy;
211 rc = fread( &b, 1, 1, fp );
217 rc = fread( &g, 1, 1, fp );
223 rc = fread( &r, 1, 1, fp );
229 rc = fread( &dummy, 1, 1, fp );
237 if ( (long)m_bytesRead > pixoff ) {
241 while ( (long)m_bytesRead < pixoff )
244 fread( &dummy,1,1,fp );
251 // set the output params
252 image = (unsigned char*)malloc( w * h );
254 if ( image != NULL ) {
255 unsigned char* outbuf = image;
259 if ( compression == 0 ) { // BI_RGB
260 for ( row = 0; row < bmHeight; row++ )
262 // which row are we working on?
263 rowOffset = (long unsigned)row * w;
266 // pixels are packed as 1 , 4 or 8 bit vals. need to unpack them
268 unsigned long mask = ( 1 << bmBitsPixel ) - 1;
269 unsigned char inbyte = 0;
271 for ( int col = 0; col < w; col++ )
275 // if we need another byte
276 if ( bit_count <= 0 ) {
278 if ( fread( &inbyte,1,1,fp ) != 1 ) {
285 // keep track of where we are in the bytes
286 bit_count -= bmBitsPixel;
287 pix = ( inbyte >> bit_count ) & mask;
289 // lookup the color from the colormap - stuff it in our buffer
291 *( outbuf + rowOffset + col ) = pix;
294 // read DWORD padding
295 while ( ( m_bytesRead - pixoff ) & 3 )
298 if ( fread( &dummy,1,1,fp ) != 1 ) {
307 else // compression != 0
310 unsigned char c, c1 = 0, *pp;
314 if ( bmBitsPixel == 8 ) {
315 while ( row < bmHeight )
322 for ( i = 0; i < c; x++, i++ )
329 // c==0x00, escape codes
332 if ( c == 0x00 ) { // end of line
335 pp = outbuf + row * bmWidth;
337 else if ( c == 0x01 ) {
340 else if ( c == 0x02 ) { // delta
345 pp = outbuf + x + row * bmWidth;
347 else // absolute mode
349 for ( i = 0; i < c; x++, i++ )
356 getc( fp ); // odd length run: read an extra pad byte
362 else if ( bmBitsPixel == 4 ) {
363 while ( row < bmHeight )
370 for ( i = 0; i < c; x++, i++ )
372 *pp = ( i & 1 ) ? ( c1 & 0x0f ) : ( ( c1 >> 4 ) & 0x0f ); pp++;
377 // c==0x00, escape codes
380 if ( c == 0x00 ) { // end of line
383 pp = outbuf + bmHeight * bmWidth;
385 else if ( c == 0x01 ) {
388 else if ( c == 0x02 ) { // delta
393 pp = outbuf + x + row * bmWidth;
395 else // absolute mode
397 for ( i = 0; i < c; x++, i++ )
399 if ( ( i & 1 ) == 0 ) {
402 *pp = ( i & 1 ) ? ( c1 & 0x0f ) : ( ( c1 >> 4 ) & 0x0f ); pp++;
405 if ( ( ( c & 3 ) == 1 ) || ( ( c & 3 ) == 2 ) ) {
406 getc( fp ); // odd length run: read an extra pad byte
431 if ( !gbmp.colors ) {
434 sprintf( Text, "Error opening %s", gbmp.name );
435 g_FuncTable.m_pfnMessageBox( g_pWnd, Text, "Bitmap", eMB_OK, eMB_ICONWARNING );
436 strcpy( gbmp.name, "" );
440 gtk_entry_set_text( GTK_ENTRY( g_object_get_data( G_OBJECT( g_pWnd ), "bmp_file" ) ), gbmp.name );
441 gtk_widget_set_sensitive( GTK_WIDGET( g_object_get_data( G_OBJECT( g_pWnd ), "bmp_reload" ) ),
442 strlen( gbmp.name ) ? TRUE : FALSE );
444 UpdatePreview( true );
447 return ( gbmp.colors != NULL );