Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // PngReader
- class PngReader {
- private:
- FILE* file;
- png_structp pngReadStruct;
- png_infop pngInfoStruct;
- void* data;
- png_bytep *dataRows;
- // Processing routines
- int sigCheck();
- bool setUp();
- void setColors();
- void rowsToData(bool bottomUp = false);
- public:
- int error;
- uint32_t width, height;
- uint32_t bitDepth;
- uint32_t channels, colorType;
- // Constructors, destructor
- PngReader();
- PngReader(std::string filename);
- virtual ~PngReader();
- // Open, close
- void open (std::string filename);
- void close ();
- void* read();
- Texture generateTexture();
- };
- /************************************************
- * Constructors, destructor *
- ************************************************/
- PngReader::PngReader() {
- file = NULL;
- error = 0;
- pngReadStruct = NULL;
- pngInfoStruct = NULL;
- }
- PngReader::PngReader(std::string filename) {
- error = 0;
- pngReadStruct = NULL;
- pngInfoStruct = NULL;
- open(filename);
- }
- PngReader::~PngReader() {
- close();
- }
- /************************************************
- * Processing *
- ************************************************/
- int PngReader::sigCheck() {
- unsigned char sig[8];
- if (error != 0 || file == NULL) return false;
- fread(sig, sizeof(char), 8, file);
- return png_sig_cmp(sig, 0, 8);
- }
- bool PngReader::setUp()
- {
- // Create the necessary structures
- pngReadStruct = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
- if (!pngReadStruct) {
- Error ("[PngReader] Failed to create read structure.");
- error = 3;
- return false;
- }
- pngInfoStruct = png_create_info_struct(pngReadStruct);
- if (!pngInfoStruct) {
- Error ("[PngReader] Failed to create info structure.");
- png_destroy_read_struct(&pngReadStruct, NULL, NULL);
- error = 4; return false;
- }
- // Set up reading
- png_init_io(pngReadStruct, file);
- png_set_sig_bytes(pngReadStruct, 8);
- // Read header
- png_read_info(pngReadStruct, pngInfoStruct);
- width = png_get_image_width(pngReadStruct, pngInfoStruct);
- height = png_get_image_height(pngReadStruct, pngInfoStruct);
- bitDepth = png_get_bit_depth(pngReadStruct, pngInfoStruct);
- channels = png_get_channels(pngReadStruct, pngInfoStruct);
- colorType = png_get_color_type(pngReadStruct, pngInfoStruct);
- png_set_interlace_handling(pngReadStruct);
- png_read_update_info(pngReadStruct, pngInfoStruct);
- return true;
- }
- void PngReader::setColors()
- {
- // We will get image in rgb format
- switch (colorType)
- {
- case PNG_COLOR_TYPE_GRAY:
- png_set_expand_gray_1_2_4_to_8(pngReadStruct);
- bitDepth = 8;
- break;
- case PNG_COLOR_TYPE_PALETTE:
- png_set_palette_to_rgb(pngReadStruct);
- channels = 3;
- break;
- }
- if (png_get_valid(pngReadStruct, pngInfoStruct, PNG_INFO_tRNS))
- {
- png_set_tRNS_to_alpha(pngReadStruct);
- ++channels;
- }
- if (bitDepth == 16) png_set_strip_16(pngReadStruct);
- }
- /************************************************
- * Open and close *
- ************************************************/
- void PngReader::open(string filename) {
- // Open file
- file = fopen(filename.c_str(), "rb");
- if (!file) {
- Error("[PngReader] Cannot open file %s", filename.c_str());
- error = 1; return;
- }
- // Check signature
- if (sigCheck()) {
- Error("[PngReader] File %s is not png.", filename.c_str());
- error = 2; return;
- }
- // Set up the image
- if (!setUp()) return;
- setColors();
- }
- void PngReader::close() {
- if (pngInfoStruct) {
- png_destroy_info_struct(pngReadStruct, &pngInfoStruct);
- pngInfoStruct = NULL;
- }
- if (pngReadStruct) {
- png_destroy_read_struct(&pngReadStruct, NULL, NULL);
- pngReadStruct = NULL;
- }
- if (data) {
- free(data); data = NULL;
- }
- if (file) {
- fclose(file); file = NULL;
- }
- }
- /************************************************
- * Reading *
- ************************************************/
- void PngReader::rowsToData(bool bottomUp)
- {
- data = malloc(width * height * bitDepth * channels / 8);
- for (uint32_t i=0; i<height; i++) {
- if (bottomUp) {
- memcpy((void*) ((size_t)data + (width * i)), dataRows[height - i - 1],
- width * bitDepth * channels / 8);
- free (dataRows[height - i - 1]);
- }
- else {
- memcpy((void*) ((size_t)data + (width * i)), dataRows[i],
- width * bitDepth * channels / 8);
- free (dataRows[i]);
- }
- }
- free(dataRows);
- }
- void* PngReader::read()
- {
- // Make sure we don't have an error
- if (!file || error) return NULL;
- // Allocate rows
- dataRows = (png_bytep*) malloc(sizeof(png_bytep) * height);
- for (uint32_t i=0; i<height; i++)
- dataRows[i] = (png_bytep) malloc(png_get_rowbytes(pngReadStruct, pngInfoStruct));
- // Read rows
- png_read_image(pngReadStruct, dataRows);
- rowsToData();
- return data;
- }
- /************************************************
- * Texture generate *
- ************************************************/
- Texture PngReader::generateTexture()
- {
- if (this->error) return Texture();
- Texture t;
- if (channels == 3)
- t.loadData(width, height, channels, GL_RGB, data);
- else if (channels == 4)
- t.loadData(width, height, channels, GL_RGBA, data);
- return t;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement