1 // -*- mode: c++; c-set-style: "stroustrup"; tab-width: 4; -*-
2 //
3 // CReaderPFM.c
4 //
5 // Copyright (C) 2004 Koji Nakamaru
6 //
7 // This program is free software; you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License as published by
9 // the Free Software Foundation; either version 2, or (at your option)
10 // any later version.
11 //
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software Foundation,
19 // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 //
21
22 #include "common.h"
23 #include "CReaderPFM.h"
24
25 static const char *_magic[] = {
26 "PF",
27 "Pf",
28 NULL,
29 };
30
31 // public functions
32
CReaderPFM()33 CReaderPFM::CReaderPFM()
34 : CReader(),
35 _is_color(true),
36 _is_swapped(false)
37 {
38 magic = _magic;
39 }
40
~CReaderPFM()41 CReaderPFM::~CReaderPFM()
42 {
43 }
44
initialize(CFile * fp,char * magic)45 bool CReaderPFM::initialize(
46 CFile *fp,
47 char *magic)
48 {
49 _is_color = (strcmp(magic, _magic[0]) == 0);
50 char buf[256];
51 if (fp->gets(buf, sizeof(buf)) == NULL
52 || buf[0] != '\n') {
53 return false;
54 }
55 if (fp->gets(buf, sizeof(buf)) == NULL
56 || buf[strlen(buf) - 1] != '\n'
57 || sscanf(buf, "%d %d", &_w, &_h) != 2
58 || _w <= 0
59 || _h <= 0) {
60 return false;
61 }
62 if (fp->gets(buf, sizeof(buf)) == NULL
63 || buf[strlen(buf) - 1] != '\n'
64 || sscanf(buf, "%f", &_scale) != 1
65 || _scale == 0.0f) {
66 return false;
67 }
68 _is_swapped = (isLittleEndian() && _scale > 0.0 || ! isLittleEndian() && _scale < 0.0);
69 return true;
70 }
71
read(CFile * fp,CImage<float,4> * image)72 void CReaderPFM::read(
73 CFile *fp,
74 CImage<float, 4> *image)
75 {
76 int c = (_is_color) ? 3 : 1;
77 for (int y = 0; y < _h; y++) {
78 float *data = image->pixel(0, 0) + (_h - 1 - y) * _w * 4;
79 for (int x = 0; x < _w; x += 64) {
80 int n0 = min(64, _w - x);
81 int n;
82 float tmp[c * 64];
83 if ((n = (fp->read(tmp, c * sizeof(float) * n0) / (c * sizeof(float)))) == 0) {
84 return;
85 }
86 image->lock();
87 float *tp = tmp;
88 if (_is_color) {
89 for (int i = 0; i < n; i++) {
90 swap4(tp);
91 *data++ = *tp++;
92 swap4(tp);
93 *data++ = *tp++;
94 swap4(tp);
95 *data++ = *tp++;
96 *data++ = 1.0;
97 }
98 } else {
99 for (int i = 0; i < n; i++) {
100 swap4(tp);
101 *data++ = *tp;
102 *data++ = *tp;
103 *data++ = *tp++;
104 *data++ = 1.0;
105 }
106 }
107 image->setChanged(true);
108 image->unlock();
109 if (n < n0) {
110 return;
111 }
112 }
113 }
114 }
115
116 // protected functions
117
swap4(float * f)118 void CReaderPFM::swap4(
119 float *f)
120 {
121 if (! _is_swapped)
122 return;
123 uint8_t *p = (uint8_t *)&f;
124 swap(p[0], p[3]);
125 swap(p[1], p[2]);
126 }
127
128 // private functions
129 // local functions
130