From 4c79db4c09622e6911088ea2391c872c2da0f461 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20Pe=C3=B1aranda?= Date: Thu, 2 May 2013 19:31:33 -0300 Subject: [PATCH] preliminary support for reading PNG images --- README | 5 +- image_read.cpp | 111 +++++++++++++++++++++++++++++++++++++++---- image_read.h | 8 ++-- pano_interface_1.pro | 6 +-- 4 files changed, 112 insertions(+), 18 deletions(-) diff --git a/README b/README index b825bed..a0abe5f 100644 --- a/README +++ b/README @@ -7,10 +7,11 @@ in development). It requires: -Qt 4, -OpenGL 3.1 or GLew 1.5.2, -freeglut (maybe it also works with glut), --libjpeg, and +-libjpeg, +-libpng, and -libnetpbm (if using any compiler other than Visual C++). -In windows, you need to get some libjpeg and libnetpbm from the GnuWin32 +In windows, you need to get libjpeg, libpng and libnetpbm from the GnuWin32 project (http://gnuwin32.sourceforge.net). Additionally, you need flex because it contains an implementation of unistd.h. diff --git a/image_read.cpp b/image_read.cpp index a2f84b4..bba18cd 100644 --- a/image_read.cpp +++ b/image_read.cpp @@ -1,6 +1,6 @@ -#include "image_read.h" +#include // for fread #include "files.h" -#include +#include "image_read.h" // The file type is determined from the file extension. enum FileType FileRead::get_file_type(const char *filename){ @@ -14,12 +14,6 @@ enum FileType FileRead::get_file_type(const char *filename){ } // if '.' was not found, the whole string is considered extension char *ext=(char*)filename+dotposition+1; // file extension - if((ext[0]=='p'||ext[0]=='P')&& - (ext[1]=='n'||ext[1]=='b'||ext[1]=='g'||ext[1]=='p'|| - ext[1]=='N'||ext[1]=='B'||ext[1]=='G'||ext[1]=='P')&& - (ext[2]=='m'||ext[2]=='M')){ - return PNM; - } if((ext[0]=='j'||ext[0]=='J')&& (ext[1]=='p'||ext[1]=='P')&& ((strlen(ext)==3&&(ext[2]=='g'||ext[2]=='G'))|| @@ -27,6 +21,17 @@ enum FileType FileRead::get_file_type(const char *filename){ (ext[3]=='g'||ext[3]=='G')))){ return JPEG; } + if((ext[0]=='p'||ext[0]=='P')&& + (ext[1]=='n'||ext[1]=='N')&& + (ext[2]=='g'||ext[2]=='G')){ + return PNG; + } + if((ext[0]=='p'||ext[0]=='P')&& + (ext[1]=='n'||ext[1]=='b'||ext[1]=='g'||ext[1]=='p'|| + ext[1]=='N'||ext[1]=='B'||ext[1]=='G'||ext[1]=='P')&& + (ext[2]=='m'||ext[2]=='M')){ + return PNM; + } return UNKNOWN; } @@ -40,6 +45,10 @@ unsigned char *FileRead::read_image(const char *new_image,int *width,int *height fprintf(stderr,"input image has JPEG format\n"); return jpgRead(new_image,width,height); break; + case PNG: + fprintf(stderr,"input image has PNG format\n"); + return pngRead(new_image,width,height); + break; #ifndef _MSC_VER case PNM: fprintf(stderr,"input image has PNM format\n"); @@ -54,8 +63,8 @@ unsigned char *FileRead::read_image(const char *new_image,int *width,int *height } unsigned char *FileRead::jpgRead(const char *texturePath, - int *outImageWidth, - int *outImageHeight){ + int *outImageWidth, + int *outImageHeight){ FILE *in_file; FOPEN_RO(in_file,texturePath) struct jpeg_decompress_struct cinfo; @@ -89,6 +98,88 @@ unsigned char *FileRead::jpgRead(const char *texturePath, return textureBytes; } +unsigned char *FileRead::pngRead(const char *texturePath, + int *outImageWidth, + int *outImageHeight){ + FILE *in_file; + FOPEN_RO(in_file,texturePath) + // read the header of the file + unsigned char header[8]; + if(fread(header,1,8,in_file)!=(unsigned long)ftell(in_file)){ + fprintf(stderr,"error reading %s\n",texturePath); + exit(-1); + } + // check the file is valid + if(png_sig_cmp(header,0,8)){ + fprintf(stderr,"%s is not a valid PNG file!\n",texturePath); + exit(-1); + } + // initialize + png_structp png_ptr=png_create_read_struct(PNG_LIBPNG_VER_STRING, + NULL,//(png_voidp)user_error_ptr, + NULL,//user_error_fn, + NULL);//user_warning_fn); + if(!png_ptr){ + fprintf(stderr,"error reading %s\n",texturePath); + exit(-1); + } + png_infop info_ptr=png_create_info_struct(png_ptr); + if (!info_ptr){ + fprintf(stderr,"error reading %s\n",texturePath); + png_destroy_read_struct(&png_ptr,(png_infopp)NULL,(png_infopp)NULL); + exit(-1); + } + if(setjmp(png_jmpbuf(png_ptr))){ + fprintf(stderr,"error reading %s\n",texturePath); + exit(-1); + } + png_init_io(png_ptr,in_file); + png_set_sig_bytes(png_ptr,8); + png_read_info(png_ptr,info_ptr); + *outImageWidth=png_get_image_width(png_ptr,info_ptr); + *outImageHeight=png_get_image_height(png_ptr,info_ptr); + png_byte color_type=png_get_color_type(png_ptr,info_ptr); + if(color_type!=PNG_COLOR_TYPE_RGB){ + fprintf(stderr,"color type of %s must be RGB\n",texturePath); + // TODO: at this moment, it is only implemented reading RGB images + exit(-1); + } + // TODO: set the value of depth according to the color type + int depth=3; // RGB + //png_byte bit_depth=png_get_bit_depth(png_ptr,info_ptr); + //int number_of_passes=png_set_interlace_handling(png_ptr); + png_read_update_info(png_ptr,info_ptr); + // allocate memory to store the texture + unsigned char *textureBytes= + (unsigned char*)malloc((*outImageWidth)* + (*outImageHeight)* + depth* + sizeof(unsigned char)); + // read the contents of the file + if(setjmp(png_jmpbuf(png_ptr))){ + fprintf(stderr,"error reading %s\n",texturePath); + exit(-1); + } + png_bytep *row_pointers= + (png_bytep*)malloc(sizeof(png_bytep)*(*outImageHeight)); + for(int y=0;y<(*outImageHeight);++y) + row_pointers[y]=(png_byte*)malloc(png_get_rowbytes(png_ptr,info_ptr)); + png_read_image(png_ptr,row_pointers); + for(int row=0;row<(*outImageHeight);++row){ + for(int j=0;j<(*outImageWidth);++j){ + for(int k=0;k +#include +#include #ifndef _MSC_VER extern "C" { @@ -14,11 +16,10 @@ extern "C" { #endif #endif -#include - enum FileType{ - PNM, JPEG, + PNG, + PNM, UNKNOWN }; @@ -29,6 +30,7 @@ class FileRead{ static unsigned char *read_image(const char*,int*,int*); private: static unsigned char *jpgRead(const char*,int*,int*); + static unsigned char *pngRead(const char*,int*,int*); #ifndef _MSC_VER static unsigned char *pnmRead(const char * const,const char*,int*,int*); #endif diff --git a/pano_interface_1.pro b/pano_interface_1.pro index aff4177..0b24c48 100644 --- a/pano_interface_1.pro +++ b/pano_interface_1.pro @@ -30,13 +30,13 @@ LIBS += -L"C:/Qt/4.8.4/bin" mac { LIBS += -L/opt/local/lib -LIBS += -lpng -lpnm -ljpeg +LIBS += -lpng -ljpeg -lpnm LIBS += -framework Carbon -framework OpenGL -framework GLUT INCLUDEPATH += /opt/local/include/netpbm/ \ /opt/local/include/ } else:unix { #LIBS += -lm -lpng -lpetsc -lglut -lGL -lnetpbm -LIBS += -lm -lglut -lGL -lGLEW -lnetpbm -ljpeg +LIBS += -lm -lglut -lGL -lGLEW -ljpeg -lpng -lnetpbm # GLee is required when the version of opengl is old #SOURCES += GLee.c #HEADERS += GLee.h @@ -56,7 +56,7 @@ LIBS += -L$${PFROOT}/freeglut/lib LIBS += -L$${PFROOT}/GnuWin32/lib LIBS += -L$${PFROOT}/GnuWin32/bin LIBS += -L$${PFROOT}/glew-1.9.0/lib -LIBS += -lglew32s -lfreeglut -lglu32 -lopengl32 -ljpeg #-llibnetpbm10 +LIBS += -lglew32s -lfreeglut -lglu32 -lopengl32 -ljpeg -lpng #-llibnetpbm10 } TARGET = pano_interface_1 -- GitLab