mirror of
https://github.com/scratchfoundation/bgfx.git
synced 2024-11-29 11:05:36 -05:00
134 lines
4 KiB
C++
134 lines
4 KiB
C++
//-----------------------------------------------------------------------------
|
|
// Product: OpenCTM tools
|
|
// File: image.cpp
|
|
// Description: Implementation of the Image class.
|
|
//-----------------------------------------------------------------------------
|
|
// Copyright (c) 2009-2010 Marcus Geelnard
|
|
//
|
|
// This software is provided 'as-is', without any express or implied
|
|
// warranty. In no event will the authors be held liable for any damages
|
|
// arising from the use of this software.
|
|
//
|
|
// Permission is granted to anyone to use this software for any purpose,
|
|
// including commercial applications, and to alter it and redistribute it
|
|
// freely, subject to the following restrictions:
|
|
//
|
|
// 1. The origin of this software must not be misrepresented; you must not
|
|
// claim that you wrote the original software. If you use this software
|
|
// in a product, an acknowledgment in the product documentation would be
|
|
// appreciated but is not required.
|
|
//
|
|
// 2. Altered source versions must be plainly marked as such, and must not
|
|
// be misrepresented as being the original software.
|
|
//
|
|
// 3. This notice may not be removed or altered from any source
|
|
// distribution.
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#include <stdexcept>
|
|
#include <cstdio>
|
|
#include <jpeglib.h>
|
|
#include <pnglite.h>
|
|
#include "image.h"
|
|
#include "common.h"
|
|
|
|
using namespace std;
|
|
|
|
|
|
/// Flip the image vertically.
|
|
void Image::FlipVertically()
|
|
{
|
|
if((mWidth <= 0) || (mHeight <= 0))
|
|
return;
|
|
|
|
for(int y = 0; y < mHeight / 2; ++ y)
|
|
{
|
|
for(int x = 0; x < mWidth; ++ x)
|
|
{
|
|
for(int k = 0; k < mComponents; ++ k)
|
|
{
|
|
unsigned char tmp = mData[(y * mWidth + x) * mComponents + k];
|
|
mData[(y * mWidth + x) * mComponents + k] = mData[((mHeight - 1 - y) * mWidth + x) * mComponents + k];
|
|
mData[((mHeight - 1 - y) * mWidth + x) * mComponents + k] = tmp;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Load image from a JPEG file.
|
|
void Image::LoadJPEG(const char * aFileName)
|
|
{
|
|
FILE * inFile = fopen(aFileName, "rb");
|
|
if(inFile != NULL)
|
|
{
|
|
// Init libjpeg resources
|
|
struct jpeg_decompress_struct cinfo;
|
|
struct jpeg_error_mgr jerr;
|
|
cinfo.err = jpeg_std_error(&jerr);
|
|
jpeg_create_decompress(&cinfo);
|
|
jpeg_stdio_src(&cinfo, inFile);
|
|
|
|
// Read JPEG header
|
|
jpeg_read_header(&cinfo, TRUE);
|
|
jpeg_start_decompress(&cinfo);
|
|
SetSize(cinfo.output_width, cinfo.output_height, cinfo.output_components);
|
|
|
|
// Read pixel data
|
|
for(int i = 0; i < mHeight; ++ i)
|
|
{
|
|
unsigned char * scanLines[1];
|
|
scanLines[0] = &mData[(mHeight - 1 - i) * mWidth * mComponents];
|
|
jpeg_read_scanlines(&cinfo, scanLines, 1);
|
|
}
|
|
|
|
// Finalize libjpeg resources
|
|
jpeg_finish_decompress(&cinfo);
|
|
jpeg_destroy_decompress(&cinfo);
|
|
|
|
// Close input file
|
|
fclose(inFile);
|
|
}
|
|
}
|
|
|
|
/// Load image from a PNG file.
|
|
void Image::LoadPNG(const char * aFileName)
|
|
{
|
|
bool success = false;
|
|
png_t p;
|
|
png_init(0, 0);
|
|
if(png_open_file(&p, aFileName) == PNG_NO_ERROR)
|
|
{
|
|
if((p.depth == 8) && ((p.color_type == PNG_GREYSCALE) ||
|
|
(p.color_type == PNG_TRUECOLOR) ||
|
|
(p.color_type == PNG_TRUECOLOR_ALPHA)) && (p.width > 0) &&
|
|
(p.height > 0) && (p.bpp >= 1) && (p.bpp <= 4))
|
|
{
|
|
SetSize(p.width, p.height, p.bpp);
|
|
if(png_get_data(&p, &mData[0]) == PNG_NO_ERROR)
|
|
{
|
|
FlipVertically();
|
|
success = true;
|
|
}
|
|
}
|
|
png_close_file(&p);
|
|
}
|
|
|
|
// Did we have an error?
|
|
if(!success)
|
|
{
|
|
Clear();
|
|
throw runtime_error("Unable to load PNG file.");
|
|
}
|
|
}
|
|
|
|
/// Load an image from a file (any supported format).
|
|
void Image::LoadFromFile(const char * aFileName)
|
|
{
|
|
string fileExt = UpperCase(ExtractFileExt(string(aFileName)));
|
|
if((fileExt == string(".JPG")) || (fileExt == string(".JPEG")))
|
|
LoadJPEG(aFileName);
|
|
else if(fileExt == string(".PNG"))
|
|
LoadPNG(aFileName);
|
|
else
|
|
throw runtime_error("Unknown input file extension.");
|
|
}
|