144 lines
4.5 KiB
C++
144 lines
4.5 KiB
C++
//=====================================================================
|
|
// Copyright 2016 (c), Advanced Micro Devices, Inc. All rights reserved.
|
|
//=====================================================================
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
// of this software and associated documentation files(the "Software"), to deal
|
|
// in the Software without restriction, including without limitation the rights
|
|
// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
|
|
// copies of the Software, and to permit persons to whom the Software is
|
|
// furnished to do so, subject to the following conditions :
|
|
//
|
|
// The above copyright notice and this permission notice shall be included in
|
|
// all copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
// THE SOFTWARE.
|
|
//
|
|
|
|
// Windows Header Files:
|
|
#ifdef _WIN32
|
|
#include <windows.h>
|
|
#endif
|
|
#include "cExr.h"
|
|
|
|
float half_conv_float(unsigned short in)
|
|
{
|
|
union fi32 {
|
|
float f;
|
|
uint i;
|
|
} u;
|
|
|
|
uint magic_exp = 113;
|
|
static const unsigned int shift_exp = 0x7c00 << 13; // shift exponent full float mask
|
|
|
|
uint half_flo = in;
|
|
|
|
u.i = (in & 0x7fff) << 13; // exponent & mantissa bits
|
|
uint exp = shift_exp & u.i; // exponent from half float
|
|
u.i += (127 - 15) << 23; // exponent adjust
|
|
|
|
//exponent special cases
|
|
if (exp == shift_exp) //Inf case
|
|
u.i += (128 - 16) << 23; // extra exp adjust
|
|
else if (exp == 0) // Zero/Denormal case
|
|
{
|
|
u.i += 1 << 23; // extra exp adjust
|
|
u.f -= (magic_exp << 23); // renormalize
|
|
}
|
|
|
|
u.i |= (in & 0x8000) << 16; // sign bit
|
|
return u.f;
|
|
}
|
|
|
|
void Exr::fileinfo(const string inf, int &width, int &height)
|
|
{
|
|
RgbaInputFile file(inf.c_str());
|
|
Box2i dw = file.dataWindow();
|
|
|
|
width = dw.max.x - dw.min.x + 1;
|
|
height = dw.max.y - dw.min.y + 1;
|
|
}
|
|
|
|
void Exr::readRgba(const string inf, Array2D<Rgba> &pix, int &w, int &h)
|
|
{
|
|
RgbaInputFile file(inf.c_str());
|
|
Box2i dw = file.dataWindow();
|
|
w = dw.max.x - dw.min.x + 1;
|
|
h = dw.max.y - dw.min.y + 1;
|
|
pix.resizeErase(h, w);
|
|
file.setFrameBuffer(&pix[0][0] - dw.min.x - dw.min.y * w, 1, w);
|
|
file.readPixels(dw.min.y, dw.max.y);
|
|
}
|
|
|
|
void Exr::writeRgba(const string outf, const Array2D<Rgba> &pix, int w, int h)
|
|
{
|
|
RgbaOutputFile file(outf.c_str(), w, h, WRITE_RGBA);
|
|
file.setFrameBuffer(&pix[0][0], 1, w);
|
|
file.writePixels(h);
|
|
}
|
|
|
|
void Rgba2Texture(Array2D<Rgba> &pixels, CMP_HALFSHORT *data, int w, int h)
|
|
{
|
|
// Save the Half Data format value into CMP_HALFSHORT bit format for processing later
|
|
for (int y = 0; y < h; ++y)
|
|
{
|
|
for (int x = 0; x < w; ++x)
|
|
{
|
|
*data = pixels[y][x].r.bits();
|
|
data++;
|
|
*data = pixels[y][x].g.bits();
|
|
data++;
|
|
*data = pixels[y][x].b.bits();
|
|
data++;
|
|
*data = pixels[y][x].a.bits();
|
|
data++;
|
|
}
|
|
}
|
|
}
|
|
|
|
void Texture2Rgba(CMP_HALFSHORT *data, Array2D<Rgba> &pixels, int w, int h, CMP_FORMAT isDeCompressed)
|
|
{
|
|
|
|
if (isDeCompressed != CMP_FORMAT_Unknown)
|
|
{
|
|
// Save the Half Data format value into a Float for processing later
|
|
for (int y = 0; y < h; ++y)
|
|
{
|
|
for (int x = 0; x < w; ++x)
|
|
{
|
|
pixels[y][x].r.setBits(*data);
|
|
data++;
|
|
pixels[y][x].g.setBits(*data);
|
|
data++;
|
|
pixels[y][x].b.setBits(*data);
|
|
data++;
|
|
pixels[y][x].a.setBits(*data);
|
|
data++;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Save the Half Data format value into a Float for processing later
|
|
for (int y = 0; y < h; ++y)
|
|
{
|
|
for (int x = 0; x < w; ++x)
|
|
{
|
|
pixels[y][x].r = *data;
|
|
data++;
|
|
pixels[y][x].g = *data;
|
|
data++;
|
|
pixels[y][x].b = *data;
|
|
data++;
|
|
pixels[y][x].a = *data;
|
|
data++;
|
|
}
|
|
}
|
|
}
|
|
} |