VIZ++ Class: PNGFileReader

 VIZ++ Class Library  VIZ++ Samples  VIZ++ ClassTree 

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.