Commit 4c79db4c authored by Luis Penaranda's avatar Luis Penaranda

preliminary support for reading PNG images

parent 42d772a0
...@@ -7,10 +7,11 @@ in development). It requires: ...@@ -7,10 +7,11 @@ in development). It requires:
-Qt 4, -Qt 4,
-OpenGL 3.1 or GLew 1.5.2, -OpenGL 3.1 or GLew 1.5.2,
-freeglut (maybe it also works with glut), -freeglut (maybe it also works with glut),
-libjpeg, and -libjpeg,
-libpng, and
-libnetpbm (if using any compiler other than Visual C++). -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 project (http://gnuwin32.sourceforge.net). Additionally, you need flex
because it contains an implementation of unistd.h. because it contains an implementation of unistd.h.
......
#include "image_read.h" #include <cstdio> // for fread
#include "files.h" #include "files.h"
#include <cstring> #include "image_read.h"
// The file type is determined from the file extension. // The file type is determined from the file extension.
enum FileType FileRead::get_file_type(const char *filename){ enum FileType FileRead::get_file_type(const char *filename){
...@@ -14,12 +14,6 @@ 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 // if '.' was not found, the whole string is considered extension
char *ext=(char*)filename+dotposition+1; // file 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')&& if((ext[0]=='j'||ext[0]=='J')&&
(ext[1]=='p'||ext[1]=='P')&& (ext[1]=='p'||ext[1]=='P')&&
((strlen(ext)==3&&(ext[2]=='g'||ext[2]=='G'))|| ((strlen(ext)==3&&(ext[2]=='g'||ext[2]=='G'))||
...@@ -27,6 +21,17 @@ enum FileType FileRead::get_file_type(const char *filename){ ...@@ -27,6 +21,17 @@ enum FileType FileRead::get_file_type(const char *filename){
(ext[3]=='g'||ext[3]=='G')))){ (ext[3]=='g'||ext[3]=='G')))){
return JPEG; 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; return UNKNOWN;
} }
...@@ -40,6 +45,10 @@ unsigned char *FileRead::read_image(const char *new_image,int *width,int *height ...@@ -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"); fprintf(stderr,"input image has JPEG format\n");
return jpgRead(new_image,width,height); return jpgRead(new_image,width,height);
break; break;
case PNG:
fprintf(stderr,"input image has PNG format\n");
return pngRead(new_image,width,height);
break;
#ifndef _MSC_VER #ifndef _MSC_VER
case PNM: case PNM:
fprintf(stderr,"input image has PNM format\n"); 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 ...@@ -54,8 +63,8 @@ unsigned char *FileRead::read_image(const char *new_image,int *width,int *height
} }
unsigned char *FileRead::jpgRead(const char *texturePath, unsigned char *FileRead::jpgRead(const char *texturePath,
int *outImageWidth, int *outImageWidth,
int *outImageHeight){ int *outImageHeight){
FILE *in_file; FILE *in_file;
FOPEN_RO(in_file,texturePath) FOPEN_RO(in_file,texturePath)
struct jpeg_decompress_struct cinfo; struct jpeg_decompress_struct cinfo;
...@@ -89,6 +98,88 @@ unsigned char *FileRead::jpgRead(const char *texturePath, ...@@ -89,6 +98,88 @@ unsigned char *FileRead::jpgRead(const char *texturePath,
return textureBytes; 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<depth;++k){
textureBytes[row*(*outImageWidth)*depth+j*depth+k]=
row_pointers[(*outImageHeight)-row-1][j*depth+k];
}
}
}
for(int row=0;row<(*outImageHeight);++row)
free(row_pointers[row]);
free(row_pointers);
fclose(in_file);
return textureBytes;
}
#ifndef _MSC_VER #ifndef _MSC_VER
unsigned char *FileRead::pnmRead(const char * const progname, unsigned char *FileRead::pnmRead(const char * const progname,
const char *texturePath, const char *texturePath,
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
#define IMAGE_READ_H #define IMAGE_READ_H
#include <utility> #include <utility>
#include <jpeglib.h>
#include <png.h>
#ifndef _MSC_VER #ifndef _MSC_VER
extern "C" { extern "C" {
...@@ -14,11 +16,10 @@ extern "C" { ...@@ -14,11 +16,10 @@ extern "C" {
#endif #endif
#endif #endif
#include <jpeglib.h>
enum FileType{ enum FileType{
PNM,
JPEG, JPEG,
PNG,
PNM,
UNKNOWN UNKNOWN
}; };
...@@ -29,6 +30,7 @@ class FileRead{ ...@@ -29,6 +30,7 @@ class FileRead{
static unsigned char *read_image(const char*,int*,int*); static unsigned char *read_image(const char*,int*,int*);
private: private:
static unsigned char *jpgRead(const char*,int*,int*); static unsigned char *jpgRead(const char*,int*,int*);
static unsigned char *pngRead(const char*,int*,int*);
#ifndef _MSC_VER #ifndef _MSC_VER
static unsigned char *pnmRead(const char * const,const char*,int*,int*); static unsigned char *pnmRead(const char * const,const char*,int*,int*);
#endif #endif
......
...@@ -30,13 +30,13 @@ LIBS += -L"C:/Qt/4.8.4/bin" ...@@ -30,13 +30,13 @@ LIBS += -L"C:/Qt/4.8.4/bin"
mac { mac {
LIBS += -L/opt/local/lib LIBS += -L/opt/local/lib
LIBS += -lpng -lpnm -ljpeg LIBS += -lpng -ljpeg -lpnm
LIBS += -framework Carbon -framework OpenGL -framework GLUT LIBS += -framework Carbon -framework OpenGL -framework GLUT
INCLUDEPATH += /opt/local/include/netpbm/ \ INCLUDEPATH += /opt/local/include/netpbm/ \
/opt/local/include/ /opt/local/include/
} else:unix { } else:unix {
#LIBS += -lm -lpng -lpetsc -lglut -lGL -lnetpbm #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 # GLee is required when the version of opengl is old
#SOURCES += GLee.c #SOURCES += GLee.c
#HEADERS += GLee.h #HEADERS += GLee.h
...@@ -56,7 +56,7 @@ LIBS += -L$${PFROOT}/freeglut/lib ...@@ -56,7 +56,7 @@ LIBS += -L$${PFROOT}/freeglut/lib
LIBS += -L$${PFROOT}/GnuWin32/lib LIBS += -L$${PFROOT}/GnuWin32/lib
LIBS += -L$${PFROOT}/GnuWin32/bin LIBS += -L$${PFROOT}/GnuWin32/bin
LIBS += -L$${PFROOT}/glew-1.9.0/lib 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 TARGET = pano_interface_1
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment