// BlockyFroggy
// Copyright © 2017 John Ryland.
// All rights reserved.
#include "Image.h"
#include "PngImage.h"
#include <stdio.h>
#include <string.h>
/*
//! @todo refactor to use slurp to implement this stuff
#include "Utilities.h"
//! @todo idea, inside CODE_GEN which is code run at compile time, do some benchmarking, and emit the more efficient code
// only problem is when cross-compiling - won't work - need to time independantly, can't do quite as automatically
#ifdef CODE_GEN
void main() {
// time doing method A
// time doing method B
// emit code of the faster version
}
#else
#include "gen.h"
#endif
// Reads in file contents of filename to dat
inline void slurp(const char* filename, std::vector<uint8_t> &dat)
{
std::ifstream file(filename, std::ifstream::ate | std::ifstream::binary);
dat.resize(file.tellg());
dat.assign((std::istreambuf_iterator<char>(file.seekg(0, std::ios::beg))), std::istreambuf_iterator<char>());
}
*/
bool LoadFile(const char* filename, ByteArray& data)
{
FILE *fp = fopen(filename, "rb");
if (!fp)
return false;
fseek(fp, 0, SEEK_END);
size_t siz = ftell(fp);
data.resize(siz);
fseek(fp, 0, SEEK_SET);
bool res = (fread(data.data(), siz, 1, fp) != 0);
fclose(fp);
return res;
}
bool SaveFile(const char* filename, const ByteArray& data)
{
FILE *fp = fopen(filename, "wb");
if (!fp)
return false;
fwrite(data.data(), data.size(), 1, fp);
fclose(fp);
return true;
}
bool DecodeTGA(const ByteArray& inData, Image& outImage)
{
const unsigned char *header = inData.data();
if (inData.size() < 18)
return false;
int bpp = header[16];
if (bpp != 24 && bpp != 32)
return false;
outImage.m_width = header[12] | (header[13] << 8);
outImage.m_height = header[14] | (header[15] << 8);
size_t siz = outImage.m_width * outImage.m_height * (bpp / 8);
if (inData.size() < 18+siz)
return false;
outImage.m_type = (bpp == 24) ? RAW_RGB_24BPP : RAW_RGBA_32BPP;
outImage.m_data.resize(siz);
memcpy(outImage.m_data.data(), inData.data() + 18, siz);
return true;
}
bool EncodeTGA(const Image& inImage, ByteArray& outData)
{
if (inImage.m_type != RAW_RGB_24BPP && inImage.m_type != RAW_RGBA_32BPP)
return false;
int bpp = (inImage.m_type == RAW_RGB_24BPP) ? 24 : 32;
size_t siz = inImage.m_width * inImage.m_height * (bpp/8);
outData.resize(18 + siz);
unsigned char *header = outData.data();
memset(header, 0, 18);
header[2] = 2;
header[12] = inImage.m_width & 0xff;
header[13] = (inImage.m_width >> 8) & 0xff;
header[14] = inImage.m_height & 0xff;
header[15] = (inImage.m_height >> 8) & 0xff;
header[16] = bpp;
memcpy(outData.data() + 18, inImage.m_data.data(), siz);
return true;
}
bool DecodePNG(const ByteArray& inData, Image& outImage)
{
return (decodePNG(outImage.m_data, outImage.m_width, outImage.m_height, inData.data(), inData.size()) == 0);
}