VIZ++ Class: PNGFileReader
|
Source code
/*
* PNGFileReader.h
* Copyright (c) 2015 Antillia.com TOSHIYUKI ARAI. ALL RIGHTS RESERVED.
*/
// 2015/07/22 This is a very simple PNG file reader based on libpng.
// See https://en.wikibooks.org/wiki/OpenGL_Programming/Intermediate/Textures
#pragma once
#include <viz++/PNGFile.h>
#include <viz++/Pair.h>
namespace VIZ {
class PNGFileReader :public PNGFile {
public:
PNGFileReader(const char* filename, bool deleteData=true)
:PNGFile(READ, filename, deleteData)
{
}
~PNGFileReader()
{
}
public:
void read(bool flipVertical = false)
{
if (validateSignature() == false) {
throw IException("Invalid header");
}
// Set the header signature bytes.
setSignatureBytes(SIGNATURE_SIZE);
// Read a png_info.
readInfo();
// Get the png_info header withoud interlaceMethod,
// compressionMethod and filterMethod.
png_uint_32 width = 0;
png_uint_32 height = 0;
int bitDepth = 0;
int colorType = 0;
getInfoHeader(width, height, bitDepth, colorType);
//setBackground();
expandPalette();
// Update the png_info
updateInfo();
// Get a row bytes.
int rowbytes = getRowBytes();
// Allocate a row_pointers.
png_bytep* rows = new png_bytep[height];
// Allocate an imageData
png_byte* imageData = new png_byte[rowbytes * height];
setImageData(imageData);
// Set the rows pointer from the imageData
for (size_t i = 0; i < height; ++i) {
if (flipVertical) {
rows[height - 1 - i] = imageData + i * rowbytes;
} else {
rows[i] = imageData + i * rowbytes;
}
}
// Read the imageData into the rows.
readImage(rows);
readEnd();
delete [] rows;
close();
}
void readInfo()
{
if (setJump()) {
throw IException("Failed to png_read_info.");
}
png_read_info(png_ptr, info_ptr);
}
// Get png_info header withoud interlaceMethod, compressionMethod and filterMethod.
int getInfoHeader(png_uint_32& width, png_uint_32& height,
int& bitDepth, int& colorType)
{
if (setJump()) {
throw IException("Failed to png_get_IHDR.");
}
return png_get_IHDR(png_ptr, info_ptr, &width, &height,
&bitDepth, &colorType,
NULL, NULL, NULL);
}
// Get png_info header
int getInfoHeader(png_uint_32& width, png_uint_32& height,
int& bitDepth, int& colorType, int& interlaceMethod,
int& compressionMethod, int& filterMethod)
{
if (setJump()) {
throw IException("Failed to png_get_IHDR.");
}
return png_get_IHDR(png_ptr, info_ptr, &width, &height,
&bitDepth, &colorType,
&interlaceMethod, &compressionMethod, &filterMethod);
}
// Read the png into imageData
void readImage(png_bytep* rows)
{
if (setJump()) {
throw IException("Failed to png_read_image.");
}
png_read_image(png_ptr, rows);
}
void readEnd()
{
if (setJump()) {
throw IException("Failed to png_read_end.");
}
png_read_end(png_ptr, NULL);
}
void setFilter(int method, int filters)
{
if (setJump()) {
throw IException("Failed to png_set_filter.");
}
png_set_filter(png_ptr, method, filters);
}
void properties()
{
printf("width: %d\n", (int)getImageWidth());
printf("height: %d\n", (int)getImageHeight());
printf("depth: %d\n", (int)getBitDepth());
printf("colorType: %s\n", colorTypeToString(getColorType() ));
}
const char* colorTypeToString(int type)
{
static Pair<int, const char*> pairs[] = {
{PNG_COLOR_TYPE_GRAY, "PNG_COLOR_TYPE_GRAY"},
{PNG_COLOR_TYPE_GRAY_ALPHA, "PNG_COLOR_TYPE_GRAY_ALPHA"},
{PNG_COLOR_TYPE_PALETTE, "PNG_COLOR_TYPE_PALETTE"},
{PNG_COLOR_TYPE_RGB, "PNG_COLOR_TYPE_RGB"},
{PNG_COLOR_TYPE_RGB_ALPHA, "PNG_COLOR_TYPE_RGB_ALPHA"},
{PNG_COLOR_MASK_PALETTE, "PNG_COLOR_MASK_PALETTE"},
{PNG_COLOR_MASK_COLOR, "PNG_COLOR_MASK_COLOR"},
{PNG_COLOR_MASK_ALPHA, "PNG_COLOR_MASK_ALPHA"},
};
const char* name = "";
for (int i = 0; i<CountOf(pairs); i++) {
if (pairs[i].first == type) {
name = pairs[i].second;
break;
}
}
return name;
}
};
}
Last modified: 10 Feb 2017
Copyright (c) 2009-2017 Antillia.com ALL RIGHTS RESERVED.