root/OpenSceneGraph/branches/OpenSceneGraph-2.8/src/osgPlugins/hdr/hdrloader.cpp @ 11264

Revision 11264, 6.2 kB (checked in by paulmartz, 5 years ago)

2.8 branch: Mergine recent changes to FBX. Revisions in this commit: r11251, r11252, r11262.

  • Property svn:mergeinfo set to
    /OpenSceneGraph/branches/OpenSceneGraph-2.8.2/src/osgPlugins/hdr/hdrloader.cpp:10664
    /OpenSceneGraph/trunk/src/osgPlugins/hdr/hdrloader.cpp:9769,9801,9816-9818,9826-9827,9837-9843,9847,9850,9854-9857,9860-9861,9865,9869,9879-9880,9885,9895,9906,9910,9912,9932-9933,9948,9959-9960,9965,9968-9969,9990,10010,10012-10014,10030,10040-10041,10053,10057,10076,10079-10080,10082,10084,10088,10128,10149,10161,10208,10264,10283,10340,10391-10392,10408,10414,10417,10422,10440,10456,10487,10491,10520,10538,10622-10623,10625,10671-10672,10697,10722,10753,10758,10761,10788,10805,10809,10818,10851,10853-10855,10858,10887,10891-10892,10914,10923,10925,10932-10933,10938,10941-10942,10945,10961,11019,11032-11035,11056,11111,11123,11127,11131,11159,11165,11173,11175,11177,11180,11182,11194,11203,11237,11251-11252,11262
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/*
2*
3* Copyright (C) 2004 Mekensleep
4*
5*    Mekensleep
6*    24 rue vieille du temple
7*    75004 Paris
8*       licensing@mekensleep.com
9*
10* This library is free software; you can redistribute it and/or
11* modify it under the terms of the GNU Lesser General Public
12* License as published by the Free Software Foundation; either
13* version 2.1 of the License, or (at your option) any later version.
14*
15* This library is distributed in the hope that it will be useful,
16* but WITHOUT ANY WARRANTY; without even the implied warranty of
17* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18* Lesser General Public License for more details.
19*
20* You should have received a copy of the GNU Lesser General Public
21* License along with this library; if not, write to the Free Software
22* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
23*
24* Author:
25*  Igor Kravtchenko <igor@obraz.net>
26*
27*/
28
29#include "hdrloader.h"
30
31#include <math.h>
32#include <memory.h>
33#include <stdio.h>
34
35#include <osgDB/FileUtils>
36
37typedef unsigned char RGBE[4];
38#define R            0
39#define G            1
40#define B            2
41#define E            3
42
43#define  MINELEN    8                // minimum scanline length for encoding
44#define  MAXELEN    0x7fff            // maximum scanline length for encoding
45
46static void rawRGBEData(RGBE *scan, int len, float *cols);
47static void workOnRGBE(RGBE *scan, int len, float *cols);
48static bool decrunch(RGBE *scanline, int len, FILE *file);
49static bool oldDecrunch(RGBE *scanline, int len, FILE *file);
50
51bool HDRLoader::isHDRFile(const char *_fileName)
52{
53    FILE *file;
54    file = osgDB::fopen(_fileName, "rb");
55    if (!file)
56        return false;
57
58    char str[10];
59    size_t numRead = fread(str, 10, 1, file);
60   
61    fclose(file);
62
63    if (numRead<1) return false;
64   
65    if (memcmp(str, "#?RADIANCE", 10) && memcmp(str, "#?RGBE", 6))
66        return false;
67
68    return true;
69}
70
71bool HDRLoader::load(const char *_fileName, const bool _rawRGBE, HDRLoaderResult &_res)
72{
73    int i;
74    char str[200];
75    FILE *file;
76
77    file = osgDB::fopen(_fileName, "rb");
78    if (!file)
79        return false;
80
81    size_t numRead = fread(str, 10, 1, file);
82
83    if (numRead<1)
84    {
85        fclose(file);
86        return false;
87    }
88   
89    if (memcmp(str, "#?RADIANCE", 10))
90    {
91        fseek(file, 0, SEEK_SET);
92        numRead = fread(str, 6, 1, file);
93        if (numRead<1 || memcmp(str, "#?RGBE", 6))
94        {
95            fclose(file);
96            return false;
97        }
98    }
99    fseek(file, 1, SEEK_CUR);
100
101    char cmd[2000];
102    i = 0;
103    char c = 0, oldc;
104    while(true) {
105        oldc = c;
106        c = fgetc(file);
107        if (c == 0xa && oldc == 0xa)
108            break;
109        cmd[i++] = c;
110    }
111
112    char reso[2000];
113    i = 0;
114    while(true) {
115        c = fgetc(file);
116        reso[i++] = c;
117        if (c == 0xa)
118            break;
119    }
120
121    int w, h;
122    if (!sscanf(reso, "-Y %d +X %d", &h, &w)) {
123        fclose(file);
124        return false;
125    }
126
127    _res.width = w;
128    _res.height = h;
129
130    int components = _rawRGBE ? 4 : 3;
131    float *cols = new float[w * h * components];
132    _res.cols = cols;
133
134    RGBE *scanline = new RGBE[w];
135    if (!scanline) {
136        fclose(file);
137        return false;
138    }
139
140    // convert image
141    cols += (h-1) * w * components;
142    for (int y = h - 1; y >= 0; y--) {
143        if (decrunch(scanline, w, file) == false)
144            break;
145        if (_rawRGBE)
146            rawRGBEData(scanline, w, cols);
147        else
148            workOnRGBE(scanline, w, cols);
149        cols -= w * components;
150    }
151
152    delete [] scanline;
153    fclose(file);
154
155    return true;
156}
157
158void rawRGBEData(RGBE *_scan, int _len, float *_cols)
159{
160    int ii = 0;
161    while (_len-- > 0) {
162        _cols[0] = _scan[0][R] / 255.0f;
163        _cols[1] = _scan[0][G] / 255.0f;
164        _cols[2] = _scan[0][B] / 255.0f;
165        _cols[3] = _scan[0][E] / 255.0f;
166        _cols += 4;
167        _scan++;
168        ii++;
169    }
170}
171
172inline float convertComponent(int _expo, int _val)
173{
174    return static_cast<float>(ldexp( static_cast<float>(_val), _expo-8));
175}
176
177void workOnRGBE(RGBE *_scan, int _len, float *_cols)
178{
179    int ii = 0;
180    while (_len-- > 0) {
181        int expo = _scan[0][E] - 128;
182        _cols[0] = convertComponent(expo, _scan[0][R]);
183        _cols[1] = convertComponent(expo, _scan[0][G]);
184        _cols[2] = convertComponent(expo, _scan[0][B]);
185        _cols += 3;
186        _scan++;
187        ii++;
188    }
189}
190
191bool decrunch(RGBE *_scanline, int _len, FILE *_file)
192{
193    int  i, j;
194
195    if (_len < MINELEN || _len > MAXELEN)
196        return oldDecrunch(_scanline, _len, _file);
197
198    i = fgetc(_file);
199    if (i != 2) {
200        fseek(_file, -1, SEEK_CUR);
201        return oldDecrunch(_scanline, _len, _file);
202    }
203
204    _scanline[0][G] = fgetc(_file);
205    _scanline[0][B] = fgetc(_file);
206    i = fgetc(_file);
207
208    if (_scanline[0][G] != 2 || _scanline[0][B] & 128) {
209        _scanline[0][R] = 2;
210        _scanline[0][E] = i;
211        return oldDecrunch(_scanline + 1, _len - 1, _file);
212    }
213
214    // read each component
215    for (i = 0; i < 4; i++) {
216        for (j = 0; j < _len; ) {
217            unsigned char code = fgetc(_file);
218            if (code > 128) { // run
219                code &= 127;
220                unsigned char val = fgetc(_file);
221                while (code--)
222                    _scanline[j++][i] = val;
223            }
224            else  {    // non-run
225                while(code--)
226                    _scanline[j++][i] = fgetc(_file);
227            }
228        }
229    }
230
231    return feof(_file) ? false : true;
232}
233
234bool oldDecrunch(RGBE *_scanline, int _len, FILE *_file)
235{
236    int i;
237    int rshift = 0;
238
239    while (_len > 0) {
240        _scanline[0][R] = fgetc(_file);
241        _scanline[0][G] = fgetc(_file);
242        _scanline[0][B] = fgetc(_file);
243        _scanline[0][E] = fgetc(_file);
244        if (feof(_file))
245            return false;
246
247        if (_scanline[0][R] == 1 &&
248            _scanline[0][G] == 1 &&
249            _scanline[0][B] == 1) {
250                for (i = _scanline[0][E] << rshift; i > 0; i--) {
251                    memcpy(&_scanline[0][0], &_scanline[-1][0], 4);
252                    _scanline++;
253                    _len--;
254                }
255                rshift += 8;
256            }
257        else {
258            _scanline++;
259            _len--;
260            rshift = 0;
261        }
262    }
263    return true;
264}
Note: See TracBrowser for help on using the browser.