Page MenuHomePhorge

PNGLoader.cpp
No OneTemporary

Size
4 KB
Referenced Files
None
Subscribers
None

PNGLoader.cpp

#include <echo/Resource/PNGLoader.h>
#include <echo/FileSystem/File.h>
#include <iostream>
namespace Echo
{
png_voidp PngAlloc(png_structp p, png_size_t s)
{
png_voidp d = (png_voidp) (new u8[s]);
return d;
}
void PngFree(png_structp p, png_voidp s)
{
u8* u8p = reinterpret_cast<u8*> (s);
delete [] u8p;
}
void PngRead(png_structp png_ptr, png_bytep data, png_size_t length)
{
voidp read_io_ptr = png_get_io_ptr(png_ptr);
if(read_io_ptr)
{
File& file = *reinterpret_cast<File*> (read_io_ptr);
file.Read(data, 1, (u32) length);
}
}
PNGLoader::PNGLoader() : mWidth(0), mHeight(0), mFormat(Texture::Formats::UNKNOWN), mFile(0)
{}
PNGLoader::~PNGLoader()
{}
bool PNGLoader::ProcessFile(File& textureFile)
{
mFile = 0;
mCurrentRow = 0;
if(!textureFile.IsOpen())
{
std::cout << "PNGLoader: Error input file is not open: " << textureFile.GetFileName() << std::endl;
return false;
}
std::cout << "LoadPNG: " << textureFile.GetFileName() << std::endl;
u8 header[8];
//Read first 8 bytes - if we couldn't then that really sucks
if(textureFile.Read((void*) (&header), 1, 8) < 8)
{
std::cout << "PNGLoader: Failed to read in first 8 bytes: " << textureFile.GetFileName() << std::endl;
return 0;
}
//Check the file is a PNG
bool is_png = !png_sig_cmp(header, 0, 8);
if(!is_png)
{
std::cout << "PNGLoader: File is not a PNG file: " << textureFile.GetFileName() << std::endl;
return 0;
}
//Allocate memory for the png stuct and the info struct
mPNGPtr = png_create_read_struct_2(PNG_LIBPNG_VER_STRING, 0, 0, 0, 0, PngAlloc, PngFree);
if(!mPNGPtr)
{
std::cout << "PNGLoader: png_create_read_struct: " << textureFile.GetFileName() << std::endl;
return 0;
}
mInfoPtr = png_create_info_struct(mPNGPtr);
if(!mInfoPtr)
{
png_destroy_read_struct(&mPNGPtr, (png_infopp) 0, (png_infopp) 0);
std::cout << "PNGLoader: png_create_info_struct:1: " << textureFile.GetFileName() << std::endl;
return 0;
}
mEndInfo = png_create_info_struct(mPNGPtr);
if(!mEndInfo)
{
png_destroy_read_struct(&mPNGPtr, &mInfoPtr, (png_infopp) 0);
std::cout << "PNGLoader: png_create_info_struct:2: " << textureFile.GetFileName() << std::endl;
return 0;
}
mFile = &textureFile;
png_set_read_fn(mPNGPtr, mFile, PngRead);
png_set_sig_bytes(mPNGPtr, 8);
png_read_png(mPNGPtr, mInfoPtr, PNG_TRANSFORM_IDENTITY, NULL);
if(mInfoPtr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
{
png_set_swap_alpha(mPNGPtr);
}
//We only support 8 bit channels at the moment
if(mInfoPtr->bit_depth == 16)
{
png_set_strip_16(mPNGPtr);
}
mRowPointers = png_get_rows(mPNGPtr, mInfoPtr);
mWidth = png_get_image_width(mPNGPtr, mInfoPtr);
mHeight = png_get_image_height(mPNGPtr, mInfoPtr);
mBytesPerPixel = png_get_channels(mPNGPtr, mInfoPtr);
switch(mBytesPerPixel)
{
case 4:
if(mInfoPtr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
{
mFormat = Texture::Formats::R8G8B8A8;
}else
if(mInfoPtr->color_type == PNG_COLOR_TYPE_RGB)
{
mFormat = Texture::Formats::R8G8B8X8;
}
break;
case 3:
mFormat = Texture::Formats::R8G8B8;
break;
case 2:
//PNG_COLOR_TYPE_GRAY_ALPHA
return false;
break;
case 1:
//PNG_COLOR_TYPE_GRAY
//PNG_COLOR_TYPE_PALETTE
return false;
break;
}
return true;
}
std::string PNGLoader::GetFileExtension() const
{
return "png";
}
u32 PNGLoader::GetWidth() const
{
return mWidth;
}
u32 PNGLoader::GetHeight() const
{
return mHeight;
}
Texture::Format PNGLoader::GetFormat() const
{
return mFormat;
}
bool PNGLoader::GetLoadInverted() const
{
return false;
}
void PNGLoader::ReadLine(u8* lineStart, u32 maxLength)
{
if(!mFile)
{
return;
}
u32 widthBytes = std::min(mWidth * mBytesPerPixel, maxLength);
//copy the data
for(u32 c = 0; c < widthBytes; ++c)
{
lineStart[c] = mRowPointers[mCurrentRow][c];
}
mCurrentRow++;
}
void PNGLoader::CleanUp()
{
png_destroy_read_struct(&mPNGPtr, &mInfoPtr, (png_infopp) 0);
}
}

File Metadata

Mime Type
text/x-c++
Expires
Thu, Jan 16, 2:00 AM (14 h, 37 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
71842
Default Alt Text
PNGLoader.cpp (4 KB)

Event Timeline