Files
filament/third_party/astcenc/Source/exr_to_htga.cpp
Philip Rideout ec31a55094 Add astcenc from ARM to third_party.
This was designed as a standalone tool rather than a library, so we are
renaming their "main" function to "standalone_main", which is described
in the tnt README.

We'll also be adding a wrapper to our imageio library.
2018-09-28 09:42:09 -07:00

213 lines
4.8 KiB
C++

/*----------------------------------------------------------------------------*/
/**
* This confidential and proprietary software may be used only as
* authorised by a licensing agreement from ARM Limited
* (C) COPYRIGHT 2011-2012 ARM Limited
* ALL RIGHTS RESERVED
*
* The entire notice above must be reproduced on all authorised
* copies and copies may only be made to the extent permitted
* by a licensing agreement from ARM Limited.
*
* @brief Program to convert FP16 images between EXR and HTGA (half-float TGA)
*
* This program uses TGA imagetypes 130/131 (non-standard);
* the data are stored as FP16 B,G,R,A (B in first two bytes, then G
* in next two, then R in the next two, then alpha in the final two
* bytes.
*/
/*----------------------------------------------------------------------------*/
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <ImfRgbaFile.h>
#include <ImfStringAttribute.h>
#include <ImfMatrixAttribute.h>
#include <ImfArray.h>
#include <ImfRgba.h>
#include <iostream>
using namespace std;
using namespace Imf;
using namespace Imath;
struct tga_header
{
uint8_t identsize;
uint8_t colormaptype;
uint8_t imagetype;
uint8_t dummied[5];
uint16_t xstart;
uint16_t ystart;
uint16_t xsize;
uint16_t ysize;
uint8_t bitsperpixel;
uint8_t descriptor;
};
void convert_exr_to_htga(const char *exr_filename, const char *htga_filename)
{
tga_header hdr = { 0, 0, 128 + 2, {0, 0, 0, 0, 0}, 0, 0, 0, 0, 64, 0x00 };
RgbaInputFile file(exr_filename);
Box2i dw = file.dataWindow();
int width = dw.max.x - dw.min.x + 1;
int height = dw.max.y - dw.min.y + 1;
Array2D < Rgba > pixels(height, width);
pixels.resizeErase(height, width);
file.setFrameBuffer(&pixels[0][0] - dw.min.x - dw.min.y * width, 1, width);
file.readPixels(dw.min.y, dw.max.y);
uint16_t *buffer = (uint16_t *) malloc(width * height * 8);
uint16_t *b2 = buffer;
int x, y;
for (y = 0; y < height; y++)
{
int y_src = y;
// int y_src = height - y - 1;
for (x = 0; x < width; x++)
{
*b2++ = pixels[y_src][x].b.bits();
*b2++ = pixels[y_src][x].g.bits();
*b2++ = pixels[y_src][x].r.bits();
*b2++ = pixels[y_src][x].a.bits();
}
}
hdr.xsize = width;
hdr.ysize = height;
FILE *f = fopen(htga_filename, "wb");
fwrite(&hdr, 1, 18, f);
fwrite(buffer, 1, 8 * width * height, f);
fclose(f);
return;
}
int convert_htga_to_exr(const char *htga_filename, const char *exr_filename)
{
int i;
tga_header hdr;
FILE *f = fopen(htga_filename, "rb");
if (!f)
return -1;
int bytes_read;
bytes_read = fread(&hdr, 1, 18, f);
if (bytes_read < 18)
{
fclose(f);
return -1;
}
int width = hdr.xsize;
int height = hdr.ysize;
int bitsperpixel = hdr.bitsperpixel;
fseek(f, hdr.identsize, SEEK_CUR);
uint16_t *buf = new uint16_t[width * height * (bitsperpixel / 16)];
int bytestoread = width * height * (bitsperpixel / 16) * 2;
bytes_read = fread(buf, 1, bytestoread, f);
fclose(f);
if (bytes_read != bytestoread)
{
delete[]buf;
return -1;
}
int pixelcount = width * height;
Rgba *pixels = new Rgba[pixelcount];
int wordsperpixel = bitsperpixel / 16;
int y;
for (y = 0; y < height; y++)
{
uint16_t *src = buf + (width * y * wordsperpixel);
int dst = width * y;
switch (hdr.bitsperpixel)
{
case 16: // Luminance
for (i = 0; i < width; i++)
{
pixels[i + dst].r.setBits(src[0]);
pixels[i + dst].g.setBits(src[0]);
pixels[i + dst].b.setBits(src[0]);
pixels[i + dst].a.setBits(0x3C00);
src++;
}
break;
case 32: // Luminance-Alpha
for (i = 0; i < width; i++)
{
pixels[i + dst].r.setBits(src[0]);
pixels[i + dst].g.setBits(src[0]);
pixels[i + dst].b.setBits(src[0]);
pixels[i + dst].a.setBits(src[1]);
src += 2;
}
break;
case 48: // RGB
for (i = 0; i < width; i++)
{
pixels[i + dst].r.setBits(src[2]);
pixels[i + dst].g.setBits(src[1]);
pixels[i + dst].b.setBits(src[0]);
pixels[i + dst].a.setBits(0x3C00);
src += 3;
}
break;
case 64:
for (i = 0; i < width; i++)
{
pixels[i + dst].r.setBits(src[2]);
pixels[i + dst].g.setBits(src[1]);
pixels[i + dst].b.setBits(src[0]);
pixels[i + dst].a.setBits(src[3]);
src += 4;
}
}
}
RgbaOutputFile file(exr_filename, width, height, WRITE_RGBA);
file.setFrameBuffer(pixels, 1, width);
file.writePixels(height);
delete[]buf;
delete[]pixels;
return 0;
}
int main(int argc, char **argv)
{
if (argc < 4)
{
printf("EXR <-> HTGA (half-float-TGA) conversion tool\n"
"Usage:\n" " %s <operation> <input_filename> <output_filename>\n" "where operation may be\n" " -q : convert from EXR to HTGA\n" " -e : convert from HTGA to EXR\n", argv[0]);
return 1;
}
if (!strcmp(argv[1], "-q"))
convert_exr_to_htga(argv[2], argv[3]);
else if (!strcmp(argv[1], "-e"))
convert_htga_to_exr(argv[2], argv[3]);
return 0;
}