|
|
Roger wrote:
> After doing some more work with demtotga I found that there appears to
> be a problem with the calculation of normalization. When I tried to use
> it on an area around the Jordan Valley (Middle East) the normalisation
> value came up as 0. I believe this was because the low point and high
> point values are equal in this region. (The Jordan valley is the lowest
> land on earth.) At a guess I would say that the problem is that the low
> point needs to be made absolute before using it in the normalisation
> calculation?
>
> Could you please make the source code available so that I can study the
> code. I am considering customising it specifically for my needs.
Sorry for such long delay. I had no time to visit povray newsgroups.I
haven't tested my program very much, it suited my needs and therefore it is
quite basic.
As I recall, USGS site said, that the sea level has height 0, all lands have
height at least 1 meter and I used this assumption. This is indeed problem
for rendering areas, which are below sea level. I don't know, what is
contained in the DEM file in this case. Solution could be to use height
source information ( from file with .SRC extension, I believe).
BTW, I suspect, that there are areas in the DEM files, which could be
corrupted. At least I found during rendering some areas with inaccurate
height field information. I am not sure, whether this is caused by
inappropriate data, by error during decompression or during my conversion.
If You found any errors, then I'd like to hear about them.
Here is code. Nothing special, but it may be good start to poke around.
/****************************************************************************
*
* FILE: demtotga.c
*
* PURPOSE: File reads binary dem file and outputs it to targa file.
*
* AUTHOR: Vahur Krouverk (vah### [at] fvaetecee)
* Parts of this program are derived from DEM2POV
*
* REVISIONS:
* #1 VK 08.11.97 : Initial revision
*
****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// size of dem file
int yrows = 6000;
int xcols = 4800;
void writeHeader(FILE *outputFile, int width, int height);
// coordinates for rectangle to convert
int starty=0;
int endy=0;
int startx=0;
int endx=0;
int min_val=32767;
int max_val=-32768;
int coeff=0;
main(int argc, char *argv[])
{
FILE *inf=0, *outf=0, *headerf=0;
char *ptr;
char filename[_MAX_PATH];
char outfilename[_MAX_PATH];
char headerfilename[_MAX_PATH];
int nodataVal=-9999;
int xcount=0, ycount=0;
short val;
char *valptr=(char *)&val;
char *buf;
char *sourcebuf;
int Argshift=0;
int bigEndian=1;
if (argc < 3) {
(void) fprintf(stderr, "DEMTOTGA v0.9: reads binary .DEM file and
converts it to 16-bit .TGA.\n");
(void) fprintf(stderr, "Written by Vahur Krouverk
(vah### [at] fvaetecee)\n");
(void) fprintf(stderr, "Based on DEM2POV v1.1c by W. D. Kirby\n");
(void) fprintf(stderr, "\nUsage: demtotga [-h headerfile] dem_file
tga_file\n\n");
(void) fprintf(stderr, " -h headerfile specifies headerfile (.HDR) for
.DEM file. \n");
exit(1);
}
if(0==strcmp(argv[1],"-h")){
int result;
char line[100];
if ((headerf = fopen(argv[2], "r")) == NULL) {
fprintf(stderr,"Error opening header file %s\n",argv[2]);
exit(1);
}
while((result = fgets(line, sizeof(line), headerf)) != NULL){
int pos=0;
if(pos=strstr(line, "NROWS")){
yrows=atoi(pos+strlen("NROWS"));
}
else if(pos=strstr(line, "NCOLS")){
xcols=atoi(pos+strlen("NCOLS"));
}
else if(pos=strstr(line, "NODATA")){
nodataVal=atoi(pos+strlen("NODATA"));
}
}
fclose(headerf);
Argshift=2;
}
strcpy(filename, argv[1+Argshift]);
strcpy(outfilename, argv[2+Argshift]);
if ((inf = fopen(filename, "r")) == NULL) {
fprintf(stderr,"Error opening input file %s\n",filename);
exit(1);
}
if ((outf = fopen(outfilename, "wb")) == NULL) {
fprintf(stderr,"Error opening output file %s\n", outfilename);
exit(1);
}
buf=malloc(xcols*2);
sourcebuf=malloc(xcols);
/* fprintf(stdout, ".DEM file width = %d, height = %d\n", xcols, yrows);*/
fprintf(stdout,"Enter start column x1 ( 1 <= x1 <= %d ) :", xcols);
fflush(stdout);
scanf("%d",&startx);
fprintf(stdout,"Enter end column x2 ( x1 <= x2 <= %d ) :", xcols);
fflush(stdout);
scanf("%d",&endx);
fprintf(stdout,"Enter start row y1 ( 1 <= y1 <= %d ) :", yrows);
fflush(stdout);
scanf("%d",&starty);
fprintf(stdout,"Enter end row y2 ( y1 <= y2 <= %d ) :", yrows);
fflush(stdout);
scanf("%d",&endy);
if(startx<1 || startx>xcols){
fprintf(stderr, "ERROR in start column range [ 1 <= start column <=
%d]\n", xcols);
exit(1);
}
if(starty<1 || starty>yrows){
fprintf(stderr, "ERROR in start row range [ 1 <= start row <= %d]\n",
yrows);
exit(1);
}
if( endx<startx || endx>xcols){
fprintf(stderr, "ERROR in end column range [ start column <= end column
<= %d]\n", xcols);
exit(1);
}
if( endy<starty || endy>yrows){
fprintf(stderr, "ERROR in end row range [ start row <= end row <=
%d]\n", yrows);
exit(1);
}
/* convert area to 0 base for dealing with arrays */
startx--;
endx;
starty--;
endy;
/*
printf(" %d, %d, %d, %d\n",startx, endx, starty, endy);
*/
fprintf(stderr, "Starting scan ...\n");
/*
read min-max values from specified part of dem file to normalize this
part (minimum value goes as 1, maximum value goes as 2**16)
sea level gets value 0
*/
/* go to data set start */
fseek(inf, starty*xcols*2, SEEK_SET);
for(ycount=starty; ycount< endy; ++ycount){
fread(buf, xcols*2, 1, inf);
/* find y start */
ptr=buf+startx*2;
for(xcount=startx; xcount<endx; xcount+=1, ptr+=2){
swab(ptr, (char*)&val, 2);
//check for sea level
if(val!=nodataVal){
if(val<min_val)
min_val=val;
if(val>max_val)
max_val=val;
}
}
}
fprintf(stderr, "Min value was %d, max value was %d \n", min_val,
max_val);
if( min_val == 32767 && max_val == -32768){
fprintf(stderr, " Warning: Nodata area (probably sea) conversion!\n");
coeff=1;
}
else{
/* calc coefficent */
coeff=(65535.0)/(max_val-min_val+1);
}
fprintf(stderr, "Coefficent for normalization is %d \n", coeff);
writeHeader(outf, endx-startx, endy-starty);
fprintf(stderr, "Starting conversion...\n");
/* go to data set start */
fseek(inf, starty*xcols*2, SEEK_SET);
for(ycount=starty;ycount< endy; ++ycount){
/* fprintf(stderr, "Working with line %d ", ycount); */
fread(buf, xcols*2, 1, inf);
/* find start position in current line*/
ptr=buf+startx*2;
for(xcount=startx; xcount<endx; xcount+=1, ptr+=2){
swab(ptr, &val, 2);
putc((char)0, outf); /* Blue empty */
if(val==nodataVal){
// sea level, put this pixel as black
putc((char)(0), outf); /* Green low byte */
putc((char)(0), outf); /* Red high byte */
}
else{
val=(val-min_val)*coeff;
putc((char)(*(valptr) ),outf); /* Green low byte */
putc((char)(*(valptr+1)), outf); /* Red high byte */
}
}
}
fprintf(stderr, "Done!\n");
fclose(outf);
fclose(inf);
free(buf);
free(sourcebuf);
return 0;
}
void writeHeader(FILE *outputFile, int width, int height)
{
int i;
fprintf(stderr,"Writing TGA header with width = %d and height = %d \n",
width, height);
/* Write TGA image header */
for (i = 0; i < 10; i++){
if (i == 2)
putc(i, outputFile);
else
putc(0, outputFile);
}
putc(0, outputFile); /* y origin set to "First_Line" */
putc(0, outputFile);
putc(width % 256, outputFile); /* write width and height */
putc(width / 256, outputFile);
putc(height % 256, outputFile);
putc(height / 256, outputFile);
putc(24, outputFile);
putc(32, outputFile);
}
Post a reply to this message
|
|