// -*- mode: c++; c-set-style: "stroustrup"; tab-width: 4; -*- // // CReaderPFM.c // // Copyright (C) 2004 Koji Nakamaru // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2, or (at your option) // any later version. // // This program 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 General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software Foundation, // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // #include "common.h" #include "CReaderPFM.h" static const char *_magic[] = { "PF", "Pf", NULL, }; // public functions CReaderPFM::CReaderPFM() : CReader(), _is_color(true), _is_swapped(false) { magic = _magic; } CReaderPFM::~CReaderPFM() { } bool CReaderPFM::initialize( CFile *fp, char *magic) { _is_color = (strcmp(magic, _magic[0]) == 0); char buf[256]; if (fp->gets(buf, sizeof(buf)) == NULL || buf[0] != '\n') { return false; } if (fp->gets(buf, sizeof(buf)) == NULL || buf[strlen(buf) - 1] != '\n' || sscanf(buf, "%d %d", &_w, &_h) != 2 || _w <= 0 || _h <= 0) { return false; } if (fp->gets(buf, sizeof(buf)) == NULL || buf[strlen(buf) - 1] != '\n' || sscanf(buf, "%f", &_scale) != 1 || _scale == 0.0f) { return false; } _is_swapped = (isLittleEndian() && _scale > 0.0 || ! isLittleEndian() && _scale < 0.0); return true; } void CReaderPFM::read( CFile *fp, CImage *image) { float *data = image->pixel(0, 0); int c = (_is_color) ? 3 : 1; for (int y = 0; y < _h; y++) { for (int x = 0; x < _w; x += 64) { int n0 = min(64, _w - x); int n; float tmp[c * 64]; if ((n = (fp->read(tmp, c * sizeof(float) * n0) / (c * sizeof(float)))) == 0) { return; } image->lock(); float *tp = tmp; if (_is_color) { for (int i = 0; i < n; i++) { swap4(tp); *data++ = *tp++; swap4(tp); *data++ = *tp++; swap4(tp); *data++ = *tp++; *data++ = 1.0; } } else { for (int i = 0; i < n; i++) { swap4(tp); *data++ = *tp; *data++ = *tp; *data++ = *tp++; *data++ = 1.0; } } image->setChanged(true); image->unlock(); if (n < n0) { return; } } } } // protected functions void CReaderPFM::swap4( float *f) { if (! _is_swapped) return; uint8_t *p = (uint8_t *)&f; swap(p[0], p[3]); swap(p[1], p[2]); } // private functions // local functions