mirror of
https://github.com/UberGames/GtkRadiant.git
synced 2024-11-29 07:02:26 +00:00
459 lines
9.7 KiB
C++
459 lines
9.7 KiB
C++
/*
|
|
GenSurf plugin for GtkRadiant
|
|
Copyright (C) 2001 David Hyde, Loki software and qeradiant.com
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Lesser General Public
|
|
License as published by the Free Software Foundation; either
|
|
version 2.1 of the License, or (at your option) any later version.
|
|
|
|
This library 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
|
|
Lesser General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Lesser General Public
|
|
License along with this library; if not, write to the Free Software
|
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
#ifdef _WIN32
|
|
// cough, cough
|
|
typedef __int32 int32_t;
|
|
typedef unsigned __int16 uint16_t;
|
|
typedef unsigned __int8 uint8_t;
|
|
typedef unsigned __int32 uint32_t;
|
|
typedef __int16 int16_t;
|
|
#endif
|
|
|
|
#include <math.h>
|
|
#include "gensurf.h"
|
|
|
|
void GenerateBitmapMapping(){
|
|
double value;
|
|
double C0, C1;
|
|
double x, y;
|
|
int i, j;
|
|
int O00,O01,O10,O11;
|
|
int r0, r1, c0, c1;
|
|
int color;
|
|
unsigned char *colors;
|
|
|
|
if ( !gbmp.colors ) {
|
|
return;
|
|
}
|
|
|
|
colors = gbmp.colors;
|
|
|
|
for ( j = 0; j <= NV; j++ )
|
|
{
|
|
y = (double)( j * ( gbmp.height - 1 ) ) / (double)NV;
|
|
r0 = (int)floor( y );
|
|
r1 = (int)ceil( y );
|
|
for ( i = 0; i <= NH; i++ )
|
|
{
|
|
x = (double)( i * ( gbmp.width - 1 ) ) / (double)NH;
|
|
c0 = (int)floor( x );
|
|
c1 = (int)ceil( x );
|
|
O00 = r0 * gbmp.width + c0;
|
|
O01 = r0 * gbmp.width + c1;
|
|
O10 = r1 * gbmp.width + c0;
|
|
O11 = r1 * gbmp.width + c1;
|
|
C0 = (double)colors[O00] + (double)( colors[O01] - colors[O00] ) * ( x - (double)c0 );
|
|
C1 = (double)colors[O10] + (double)( colors[O11] - colors[O10] ) * ( x - (double)c0 );
|
|
color = (int)( C0 + ( C1 - C0 ) * ( y - r0 ) );
|
|
|
|
value = CalculateSnapValue( gbmp.black_value + color * ( ( gbmp.white_value - gbmp.black_value ) / 255. ) );
|
|
|
|
switch ( Plane )
|
|
{
|
|
case PLANE_XZ0:
|
|
case PLANE_XZ1:
|
|
xyz[i][j].p[1] = value;
|
|
break;
|
|
case PLANE_YZ0:
|
|
case PLANE_YZ1:
|
|
xyz[i][j].p[0] = value;
|
|
break;
|
|
default:
|
|
xyz[i][j].p[2] = value;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static unsigned char* OpenBitmapFile(){
|
|
#define INVALID_FORMAT do { \
|
|
fprintf( stderr,"%s:%d: Error file '%s' is malformed.\n",__FILE__,__LINE__,gbmp.name ); \
|
|
fclose( fp ); \
|
|
return NULL; \
|
|
} while ( 0 )
|
|
|
|
int32_t bmWidth;
|
|
int32_t bmHeight;
|
|
uint16_t bmPlanes;
|
|
uint16_t bmBitsPixel;
|
|
uint8_t m1,m2;
|
|
uint32_t sizeimage;
|
|
int16_t res1,res2;
|
|
int32_t filesize, pixoff;
|
|
int32_t bmisize, compression;
|
|
int32_t xscale, yscale;
|
|
int32_t colors, impcol;
|
|
uint32_t m_bytesRead = 0;
|
|
unsigned char *image;
|
|
FILE *fp;
|
|
|
|
fp = fopen( gbmp.name, "rb" );
|
|
if ( fp == NULL ) {
|
|
fprintf( stderr,"Error: Invalid filename '%s'\n",gbmp.name );
|
|
return NULL;
|
|
}
|
|
|
|
long rc;
|
|
rc = fread( &m1, 1, 1, fp );
|
|
m_bytesRead++;
|
|
if ( rc == -1 ) {
|
|
fclose( fp );
|
|
return NULL;
|
|
}
|
|
|
|
rc = fread( &m2, 1, 1, fp );
|
|
m_bytesRead++;
|
|
if ( ( m1 != 'B' ) || ( m2 != 'M' ) ) {
|
|
INVALID_FORMAT;
|
|
}
|
|
|
|
rc = fread( (uint32_t*)&( filesize ),4,1,fp ); m_bytesRead += 4;
|
|
if ( rc != 1 ) {
|
|
INVALID_FORMAT;
|
|
}
|
|
|
|
rc = fread( (uint16_t*)&( res1 ),2,1,fp ); m_bytesRead += 2;
|
|
if ( rc != 1 ) {
|
|
INVALID_FORMAT;
|
|
}
|
|
|
|
rc = fread( (uint16_t*)&( res2 ),2,1,fp ); m_bytesRead += 2;
|
|
if ( rc != 1 ) {
|
|
INVALID_FORMAT;
|
|
}
|
|
|
|
rc = fread( (uint32_t*)&( pixoff ),4,1,fp ); m_bytesRead += 4;
|
|
if ( rc != 1 ) {
|
|
INVALID_FORMAT;
|
|
}
|
|
|
|
rc = fread( (uint32_t*)&( bmisize ),4,1,fp ); m_bytesRead += 4;
|
|
if ( rc != 1 ) {
|
|
INVALID_FORMAT;
|
|
}
|
|
|
|
rc = fread( (uint32_t *)&( bmWidth ),4,1,fp ); m_bytesRead += 4;
|
|
if ( rc != 1 ) {
|
|
INVALID_FORMAT;
|
|
}
|
|
|
|
rc = fread( (uint32_t*)&( bmHeight ),4,1,fp ); m_bytesRead += 4;
|
|
if ( rc != 1 ) {
|
|
INVALID_FORMAT;
|
|
}
|
|
|
|
rc = fread( (uint16_t*)&( bmPlanes ),2,1,fp ); m_bytesRead += 2;
|
|
if ( rc != 1 ) {
|
|
INVALID_FORMAT;
|
|
}
|
|
|
|
rc = fread( (uint16_t*)&( bmBitsPixel ),2,1,fp ); m_bytesRead += 2;
|
|
if ( rc != 1 ) {
|
|
INVALID_FORMAT;
|
|
}
|
|
|
|
rc = fread( (uint32_t*)&( compression ),4,1,fp ); m_bytesRead += 4;
|
|
if ( rc != 1 ) {
|
|
INVALID_FORMAT;
|
|
}
|
|
|
|
rc = fread( (uint32_t*)&( sizeimage ),4,1,fp ); m_bytesRead += 4;
|
|
if ( rc != 1 ) {
|
|
INVALID_FORMAT;
|
|
}
|
|
|
|
rc = fread( (uint32_t*)&( xscale ),4,1,fp ); m_bytesRead += 4;
|
|
if ( rc != 1 ) {
|
|
INVALID_FORMAT;
|
|
}
|
|
|
|
rc = fread( (uint32_t*)&( yscale ),4,1,fp ); m_bytesRead += 4;
|
|
if ( rc != 1 ) {
|
|
INVALID_FORMAT;
|
|
}
|
|
|
|
rc = fread( (uint32_t*)&( colors ),4,1,fp ); m_bytesRead += 4;
|
|
if ( rc != 1 ) {
|
|
INVALID_FORMAT;
|
|
}
|
|
|
|
rc = fread( (uint32_t*)&( impcol ),4,1,fp ); m_bytesRead += 4;
|
|
if ( rc != 1 ) {
|
|
INVALID_FORMAT;
|
|
}
|
|
|
|
if ( bmBitsPixel != 8 ) {
|
|
g_FuncTable.m_pfnMessageBox( g_pWnd, "This is not an 8-bit image. GenSurf can't use it.",
|
|
"Bitmap", MB_ICONEXCLAMATION, NULL );
|
|
INVALID_FORMAT;
|
|
}
|
|
|
|
if ( colors == 0 ) {
|
|
colors = 1 << bmBitsPixel;
|
|
}
|
|
|
|
if ( bmBitsPixel != 24 ) {
|
|
int i;
|
|
for ( i = 0; i < colors; i++ )
|
|
{
|
|
unsigned char r,g, b, dummy;
|
|
|
|
rc = fread( &b, 1, 1, fp );
|
|
m_bytesRead++;
|
|
if ( rc != 1 ) {
|
|
INVALID_FORMAT;
|
|
}
|
|
|
|
rc = fread( &g, 1, 1, fp );
|
|
m_bytesRead++;
|
|
if ( rc != 1 ) {
|
|
INVALID_FORMAT;
|
|
}
|
|
|
|
rc = fread( &r, 1, 1, fp );
|
|
m_bytesRead++;
|
|
if ( rc != 1 ) {
|
|
INVALID_FORMAT;
|
|
}
|
|
|
|
rc = fread( &dummy, 1, 1, fp );
|
|
m_bytesRead++;
|
|
if ( rc != 1 ) {
|
|
INVALID_FORMAT;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( (long)m_bytesRead > pixoff ) {
|
|
INVALID_FORMAT;
|
|
}
|
|
|
|
while ( (long)m_bytesRead < pixoff )
|
|
{
|
|
char dummy;
|
|
fread( &dummy,1,1,fp );
|
|
m_bytesRead++;
|
|
}
|
|
|
|
int w = bmWidth;
|
|
int h = bmHeight;
|
|
|
|
// set the output params
|
|
image = (unsigned char*)malloc( w * h );
|
|
|
|
if ( image != NULL ) {
|
|
unsigned char* outbuf = image;
|
|
long row = 0;
|
|
long rowOffset = 0;
|
|
|
|
if ( compression == 0 ) { // BI_RGB
|
|
for ( row = 0; row < bmHeight; row++ )
|
|
{
|
|
// which row are we working on?
|
|
rowOffset = (long unsigned)row * w;
|
|
|
|
{
|
|
// pixels are packed as 1 , 4 or 8 bit vals. need to unpack them
|
|
int bit_count = 0;
|
|
unsigned long mask = ( 1 << bmBitsPixel ) - 1;
|
|
unsigned char inbyte = 0;
|
|
|
|
for ( int col = 0; col < w; col++ )
|
|
{
|
|
int pix = 0;
|
|
|
|
// if we need another byte
|
|
if ( bit_count <= 0 ) {
|
|
bit_count = 8;
|
|
if ( fread( &inbyte,1,1,fp ) != 1 ) {
|
|
free( image );
|
|
INVALID_FORMAT;
|
|
}
|
|
m_bytesRead++;
|
|
}
|
|
|
|
// keep track of where we are in the bytes
|
|
bit_count -= bmBitsPixel;
|
|
pix = ( inbyte >> bit_count ) & mask;
|
|
|
|
// lookup the color from the colormap - stuff it in our buffer
|
|
// swap red and blue
|
|
*( outbuf + rowOffset + col ) = pix;
|
|
}
|
|
|
|
// read DWORD padding
|
|
while ( ( m_bytesRead - pixoff ) & 3 )
|
|
{
|
|
char dummy;
|
|
if ( fread( &dummy,1,1,fp ) != 1 ) {
|
|
free( image );
|
|
INVALID_FORMAT;
|
|
}
|
|
m_bytesRead++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else // compression != 0
|
|
{
|
|
int i, x = 0;
|
|
unsigned char c, c1 = 0, *pp;
|
|
row = 0;
|
|
pp = outbuf;
|
|
|
|
if ( bmBitsPixel == 8 ) {
|
|
while ( row < bmHeight )
|
|
{
|
|
c = getc( fp );
|
|
|
|
if ( c ) {
|
|
// encoded mode
|
|
c1 = getc( fp );
|
|
for ( i = 0; i < c; x++, i++ )
|
|
{
|
|
*pp = c1; pp++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// c==0x00, escape codes
|
|
c = getc( fp );
|
|
|
|
if ( c == 0x00 ) { // end of line
|
|
row++;
|
|
x = 0;
|
|
pp = outbuf + row * bmWidth;
|
|
}
|
|
else if ( c == 0x01 ) {
|
|
break; // end of pic
|
|
}
|
|
else if ( c == 0x02 ) { // delta
|
|
c = getc( fp );
|
|
x += c;
|
|
c = getc( fp );
|
|
row += c;
|
|
pp = outbuf + x + row * bmWidth;
|
|
}
|
|
else // absolute mode
|
|
{
|
|
for ( i = 0; i < c; x++, i++ )
|
|
{
|
|
c1 = getc( fp );
|
|
*pp = c1; pp++;
|
|
}
|
|
|
|
if ( c & 1 ) {
|
|
getc( fp ); // odd length run: read an extra pad byte
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if ( bmBitsPixel == 4 ) {
|
|
while ( row < bmHeight )
|
|
{
|
|
c = getc( fp );
|
|
|
|
if ( c ) {
|
|
// encoded mode
|
|
c1 = getc( fp );
|
|
for ( i = 0; i < c; x++, i++ )
|
|
{
|
|
*pp = ( i & 1 ) ? ( c1 & 0x0f ) : ( ( c1 >> 4 ) & 0x0f ); pp++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// c==0x00, escape codes
|
|
c = getc( fp );
|
|
|
|
if ( c == 0x00 ) { // end of line
|
|
row++;
|
|
x = 0;
|
|
pp = outbuf + bmHeight * bmWidth;
|
|
}
|
|
else if ( c == 0x01 ) {
|
|
break; // end of pic
|
|
}
|
|
else if ( c == 0x02 ) { // delta
|
|
c = getc( fp );
|
|
x += c;
|
|
c = getc( fp );
|
|
row += c;
|
|
pp = outbuf + x + row * bmWidth;
|
|
}
|
|
else // absolute mode
|
|
{
|
|
for ( i = 0; i < c; x++, i++ )
|
|
{
|
|
if ( ( i & 1 ) == 0 ) {
|
|
c1 = getc( fp );
|
|
}
|
|
*pp = ( i & 1 ) ? ( c1 & 0x0f ) : ( ( c1 >> 4 ) & 0x0f ); pp++;
|
|
}
|
|
|
|
if ( ( ( c & 3 ) == 1 ) || ( ( c & 3 ) == 2 ) ) {
|
|
getc( fp ); // odd length run: read an extra pad byte
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
fclose( fp );
|
|
|
|
gbmp.width = w;
|
|
gbmp.height = h;
|
|
if ( gbmp.colors ) {
|
|
free( gbmp.colors );
|
|
}
|
|
gbmp.colors = image;
|
|
return image;
|
|
|
|
|
|
}
|
|
|
|
bool OpenBitmap(){
|
|
|
|
OpenBitmapFile();
|
|
|
|
if ( !gbmp.colors ) {
|
|
g_print( "failed to load file gbmp %s\n",gbmp.name );
|
|
char Text[256];
|
|
|
|
sprintf( Text, "Error opening %s", gbmp.name );
|
|
g_FuncTable.m_pfnMessageBox( g_pWnd, Text, "Bitmap", MB_ICONEXCLAMATION, NULL );
|
|
strcpy( gbmp.name, "" );
|
|
}
|
|
|
|
if ( g_pWnd ) {
|
|
gtk_entry_set_text( GTK_ENTRY( g_object_get_data( G_OBJECT( g_pWnd ), "bmp_file" ) ), gbmp.name );
|
|
gtk_widget_set_sensitive( GTK_WIDGET( g_object_get_data( G_OBJECT( g_pWnd ), "bmp_reload" ) ),
|
|
strlen( gbmp.name ) ? TRUE : FALSE );
|
|
|
|
UpdatePreview( true );
|
|
}
|
|
|
|
return ( gbmp.colors != NULL );
|
|
}
|