forked from plepers/hdr2png
-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.cpp
133 lines (80 loc) · 2.62 KB
/
main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#include "main.h"
using namespace TCLAP;
using namespace std;
int main(int argc, char* argv[])
{
CmdLine cmd("hdr2png - convert radiance RGBE to png RGBA", ' ', "0.1");
ValueArg<string> a_input("i","input","input hdr file",true,"","string", cmd );
ValueArg<string> a_output("o","output","output png file",true,"","string", cmd );
SwitchArg a_rebase("r","rebase", "maximize exponent range", true);
cmd.add( a_rebase );
cmd.parse( argc, argv );
const char* input = a_input.getValue().c_str();
const char* output = a_output.getValue().c_str();
const bool rebase = a_rebase.getValue();
//==================================================
// Load hdr file
//==================================================
HDRLoaderResult* hdrData = new HDRLoaderResult();
HDRLoader* hdrLoader = new HDRLoader();
if( ! hdrLoader->load( input, *hdrData ) ) {
printf( "error loading %s \n", input );
return 1;
}
printf( "input loaded \n size : %i*%i \n range %i>%i \n", hdrData->width, hdrData->height , hdrData->eMin, hdrData->eMax );
double base;
if( rebase )
base = getNewBase( hdrData->eMin, hdrData->eMax );
else
base = 2.0f;
printf( "f32toRgbe (base : %f)\n", base );
const unsigned char* rgbe = f32toRgbe( hdrData->cols, hdrData->width, hdrData->height, base );
printf( "encode png \n" );
/*Encode the image*/
unsigned error = lodepng_encode32_file( output, rgbe, hdrData->width, hdrData->height );
/*if there's an error, display it*/
if(error) printf("error %u: %s \n", error, lodepng_error_text(error));
delete hdrLoader;
delete hdrData;
return 0;
}
double getNewBase( char min, char max ) {
double newbaseMax = pow( pow( 2.0, (double)max ), 1.0/128.0 );
double newbaseMin = pow( pow( 2.0, (double)min ), -1.0/128.0 );
if( newbaseMax > newbaseMin)
return newbaseMax;
return newbaseMin;
}
unsigned char* f32toRgbe( float* pixels, int w, int h, double base ) {
//base = 2.0;
int j;
int resSize = w*h;
unsigned char* rgbe = ( unsigned char* ) malloc( resSize*4*sizeof( unsigned char* ) );
float r, g, b;
double e, re;
int f;
double logbase = log( base );
int c = 0;
int fc = 0;
for (j = 0; j < resSize; j++) {
fc = j*3;
c = j*4;
r = pixels[fc];
g = pixels[fc+1];
b = pixels[fc+2];
re = max( r, max( g, b ) );
f = int( ceil( log( re ) / logbase ) );
if( f < -128.0f ) f = -128.0f;
if( f > 127.0f ) f = 127.0f;
e = pow( base, f );
r = r*255.0f / e;
g = g*255.0f / e;
b = b*255.0f / e;
f += 128.0f;
rgbe[c] = char( r );
rgbe[c+1] = char( g );
rgbe[c+2] = char( b );
rgbe[c+3] = char( f );
}
return rgbe;
}