diff --git a/files.h b/files.h new file mode 100644 index 0000000000000000000000000000000000000000..cbcd632ffa0791caddc27b2359ca161f9b28d498 --- /dev/null +++ b/files.h @@ -0,0 +1,29 @@ +#ifndef FILES_H +#define FILES_H + +#ifdef _MSC_VER + #include + #include + #define GET_WORKDIR _getcwd + #define OPEN_FILE _open + #define LSEEK_FD _lseek + #define FOPEN_RO(_descriptor,_filename) \ + if(fopen_s(&(_descriptor),_filename,"r")){ \ + fprintf(stderr,"unable to open file '%s'\n",_filename); \ + exit(-1); \ + } +#else + #include // for fopen and fclose + #include // for getcwd, getpwuid, getuid + #define GET_WORKDIR getcwd + #define OPEN_FILE open + #define LSEEK_FD lseek + #define FOPEN_RO(_descriptor,_filename) \ + _descriptor=fopen(_filename,"r"); \ + if((_descriptor)==NULL){ \ + fprintf(stderr,"unable to open file '%s'\n",_filename); \ + exit(-1); \ + } +#endif + +#endif // FILES_H diff --git a/image_read.cpp b/image_read.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a2f84b4c0d1d20d12b063fd8653bf2b187081a58 --- /dev/null +++ b/image_read.cpp @@ -0,0 +1,131 @@ +#include "image_read.h" +#include "files.h" +#include + +// The file type is determined from the file extension. +enum FileType FileRead::get_file_type(const char *filename){ + // find the last '.' in the file name + int dotposition=-1; + for(int i=strlen(filename)-1;i>=0;--i){ + if(filename[i]=='.'){ + dotposition=i; + break; + } + } + // 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'))|| + (strlen(ext)==4&&(ext[2]=='e'||ext[2]=='E')&& + (ext[3]=='g'||ext[3]=='G')))){ + return JPEG; + } + return UNKNOWN; +} + +unsigned char *FileRead::read_image(const char *new_image,int *width,int *height){ +#ifndef _MSC_VER + // the progname is only used for reading the PNM format + const char * const progname=(char*)(PROGNAME); +#endif + switch(get_file_type(new_image)){ + case JPEG: + fprintf(stderr,"input image has JPEG format\n"); + return jpgRead(new_image,width,height); + break; +#ifndef _MSC_VER + case PNM: + fprintf(stderr,"input image has PNM format\n"); + return pnmRead(progname,new_image,width,height); + break; +#endif + default: // UNKNOWN + fprintf(stderr,"%s: unknown file format\n",new_image); + exit(-1); + } + return NULL; +} + +unsigned char *FileRead::jpgRead(const char *texturePath, + int *outImageWidth, + int *outImageHeight){ + FILE *in_file; + FOPEN_RO(in_file,texturePath) + struct jpeg_decompress_struct cinfo; + struct jpeg_error_mgr jerr; + cinfo.err=jpeg_std_error(&jerr); + JSAMPROW row_pointer[1]; + jpeg_create_decompress(&cinfo); + jpeg_stdio_src(&cinfo,in_file); + jpeg_read_header(&cinfo,0); + jpeg_start_decompress(&cinfo); + *outImageWidth=cinfo.output_width; + *outImageHeight=cinfo.output_height; + int depth=cinfo.num_components; + int textureSize=(*outImageWidth)*(*outImageHeight)*depth; + unsigned char *textureBytes= + (unsigned char*)malloc(textureSize*sizeof(unsigned char)); + unsigned long scanline=*outImageHeight; + row_pointer[0]=(unsigned char*)malloc((*outImageWidth)* + depth* + sizeof(unsigned char)); + while(cinfo.output_scanline<(unsigned)*outImageHeight){ + --scanline; + jpeg_read_scanlines(&cinfo,row_pointer,1); + for(int i=0;i<(*outImageWidth)*depth;++i){ + textureBytes[scanline*(*outImageWidth)*depth+i]=row_pointer[0][i]; + } + } + fclose(in_file); + jpeg_finish_decompress(&cinfo); + jpeg_destroy_decompress(&cinfo); + return textureBytes; +} + +#ifndef _MSC_VER +unsigned char *FileRead::pnmRead(const char * const progname, + const char *texturePath, + int *outImageWidth, + int *outImageHeight){ + struct pam inpam; + pm_init(progname, 0); + FILE *in_file; + FOPEN_RO(in_file,texturePath) +#ifdef PAM_STRUCT_SIZE + pnm_readpaminit(in_file,&inpam,PAM_STRUCT_SIZE(tuple_type)); +#else + pnm_readpaminit(in_file,&inpam,sizeof(struct pam)); +#endif + *outImageWidth=inpam.width; + *outImageHeight=inpam.height; + int textureSize= + (*outImageWidth)* + (*outImageHeight)* + inpam.depth* + inpam.bytes_per_sample; + unsigned char *textureBytes= + (unsigned char*)malloc(textureSize*sizeof(unsigned char)); + tuple *tuplerow=pnm_allocpamrow(&inpam); + for(int row=0;row<*outImageHeight;row++) { + int column; + pnm_readpamrow(&inpam,tuplerow); + for (column=0;column<*outImageWidth;++column) { + unsigned int plane; + for(plane=0;plane + +#ifndef _MSC_VER +extern "C" { +#include +#include +#include +} + #ifndef _MSC_VER + #define PROGNAME "pano_interface" + #endif +#endif + +#include + +enum FileType{ + PNM, + JPEG, + UNKNOWN +}; + +class FileRead{ + private: + static enum FileType get_file_type(const char*); + protected: + static unsigned char *read_image(const char*,int*,int*); + private: + static unsigned char *jpgRead(const char*,int*,int*); +#ifndef _MSC_VER + static unsigned char *pnmRead(const char * const,const char*,int*,int*); +#endif +}; + +#endif // IMAGE_READ_H diff --git a/openglcanvas.cpp b/openglcanvas.cpp index 8ffad2e13eb06352eb3fc087765b11da5e9fa221..c705bc8475555f7af18416acfc0a2d4ef64ffb97 100644 --- a/openglcanvas.cpp +++ b/openglcanvas.cpp @@ -11,34 +11,10 @@ #else #include // for getpwuid #endif -#include // for fopen, fclose, getc +#include // for getc #include -#ifdef _MSC_VER - #include - #define GET_WORKDIR _getcwd - #define OPEN_FILE _open - #define LSEEK_FD _lseek - #define FOPEN_RO(_descriptor,_filename) \ - if(fopen_s(&(_descriptor),_filename,"r")){ \ - fprintf(stderr,"unable to open file '%s'\n",_filename); \ - exit(-1); \ - } -#else - // unistd was included above - #define GET_WORKDIR getcwd - #define OPEN_FILE open - #define LSEEK_FD lseek - #define FOPEN_RO(_descriptor,_filename) \ - _descriptor=fopen(_filename,"r"); \ - if((_descriptor)==NULL){ \ - fprintf(stderr,"unable to open file '%s'\n",_filename); \ - exit(-1); \ - } -#endif -#ifndef _MSC_VER - #define PROGNAME "pano_interface" -#endif +#include "files.h" #define VERT_SHADER_FILE "test_vertex_shader.vert" #define FRAG_SHADER_FILE "fragment_shader.frag" @@ -283,68 +259,23 @@ void OpenGLCanvas::read_config_file(){ emit max_fov_changed((int)fov_max); } -// The file type is determined from the file extension. -enum FileType OpenGLCanvas::get_file_type(const char *filename){ - // find the last '.' in the file name - int dotposition=-1; - for(int i=strlen(filename)-1;i>=0;--i){ - if(filename[i]=='.'){ - dotposition=i; - break; - } - } - // 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'))|| - (strlen(ext)==4&&(ext[2]=='e'||ext[2]=='E')&& - (ext[3]=='g'||ext[3]=='G')))){ - return JPEG; - } - return UNKNOWN; -} - void OpenGLCanvas::load_image(const char *new_image){ - int width,height; -#ifndef _MSC_VER - // the progname is only used for reading the PNM format - const char * const progname=(char*)(PROGNAME); -#endif - unsigned char *textureBytes=NULL; - int textureSize; - switch(get_file_type(new_image)){ - case JPEG: - fprintf(stderr,"input image has JPEG format\n"); - textureSize=jpgGetTextureSize(new_image); - textureBytes=(unsigned char*)malloc(textureSize); - jpgReadTextureBytes(new_image,textureBytes,&width,&height); - break; -#ifndef _MSC_VER - case PNM: - fprintf(stderr,"input image has PNM format\n"); - textureSize=pnmGetTextureSize(progname,new_image); - textureBytes=(unsigned char*)malloc(textureSize); - pnmReadTextureBytes(progname,new_image,textureBytes,&width,&height); - break; -#endif - default: // UNKNOWN - fprintf(stderr,"%s: unknown file format\n",new_image); - exit(-1); - } + unsigned char *textureBytes=read_image(new_image,&image_size_x,&image_size_y); glPixelStorei(GL_UNPACK_ALIGNMENT,1); GLuint tex; glGenTextures(1,&tex); glBindTexture(GL_TEXTURE_2D,tex); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); - glTexImage2D(GL_TEXTURE_2D,0, GL_RGB, width,height,0,GL_RGB,GL_UNSIGNED_BYTE,textureBytes); + glTexImage2D(GL_TEXTURE_2D, + 0, + GL_RGB, + image_size_x, + image_size_y, + 0, + GL_RGB, + GL_UNSIGNED_BYTE, + textureBytes); } void OpenGLCanvas::change_input_image(){ @@ -609,116 +540,6 @@ void OpenGLCanvas::define_triangle_indices(unsigned int * indices, int m, int n) } -#ifndef _MSC_VER -int OpenGLCanvas::pnmGetTextureSize(const char * const progname, const char * texturePath) -{ - struct pam inpam; - pm_init(progname, 0); - FILE *in_file; - FOPEN_RO(in_file,texturePath) -#ifdef PAM_STRUCT_SIZE - pnm_readpaminit(in_file,&inpam,PAM_STRUCT_SIZE(tuple_type)); -#else - pnm_readpaminit(in_file,&inpam,sizeof(struct pam)); -#endif - image_size_x=inpam.width; - image_size_y=inpam.height; - int size = image_size_x*image_size_y*inpam.depth*inpam.bytes_per_sample; - pm_close(in_file); - return size; -} - -void OpenGLCanvas::pnmReadTextureBytes(const char * const progname, - const char * texturePath, - unsigned char * textureBytes, - int * outImageWidth, - int * outImageHeight) -{ - struct pam inpam; - tuple * tuplerow; - int row; - - pm_init(progname, 0); - FILE *in_file; - FOPEN_RO(in_file,texturePath); - -#ifdef PAM_STRUCT_SIZE - pnm_readpaminit(in_file,&inpam,PAM_STRUCT_SIZE(tuple_type)); -#else - pnm_readpaminit(in_file,&inpam,sizeof(struct pam)); -#endif - - tuplerow = pnm_allocpamrow(&inpam); - - for (row = 0; row < inpam.height; row++) { - int column; - pnm_readpamrow(&inpam, tuplerow); - for (column = 0; column < inpam.width; ++column) { - unsigned int plane; - for (plane = 0; plane < inpam.depth; ++plane) { - textureBytes[(inpam.height-row-1)*3*inpam.width+3*column+plane] = tuplerow[column][plane]; - } - } - } - - pnm_freepamrow(tuplerow); - - *outImageWidth = inpam.width; - *outImageHeight = inpam.height; - - pm_close(in_file); -} -#endif - -int OpenGLCanvas::jpgGetTextureSize(const char *texturePath) -{ - FILE *in_file; - FOPEN_RO(in_file,texturePath) - struct jpeg_decompress_struct cinfo; - struct jpeg_error_mgr jerr; - cinfo.err=jpeg_std_error(&jerr); - jpeg_create_decompress(&cinfo); - jpeg_stdio_src(&cinfo,in_file); - jpeg_read_header(&cinfo,0); - jpeg_start_decompress(&cinfo); - image_size_x=cinfo.output_width; - image_size_y=cinfo.output_height; - int size=image_size_x*image_size_y*cinfo.num_components; - fclose(in_file); - return size; -} - -void OpenGLCanvas::jpgReadTextureBytes(const char *texturePath, - unsigned char *textureBytes, - int *outImageWidth, - int *outImageHeight) -{ - FILE *in_file; - FOPEN_RO(in_file,texturePath); - struct jpeg_decompress_struct cinfo; - struct jpeg_error_mgr jerr; - cinfo.err=jpeg_std_error(&jerr); - JSAMPROW row_pointer[1]; - jpeg_create_decompress(&cinfo); - jpeg_stdio_src(&cinfo,in_file); - jpeg_read_header(&cinfo,0); - jpeg_start_decompress(&cinfo); - int depth=cinfo.num_components; - unsigned long scanline=image_size_y; - row_pointer[0]=(unsigned char*)malloc(image_size_x*depth); - while(cinfo.output_scanlineh) @@ -736,7 +557,6 @@ char * OpenGLCanvas::textFileRead(char *fn) { count = LSEEK_FD(f, 0, SEEK_END); // close(f); if (fn != NULL) { - //fp = fopen(fn,"rt"); FOPEN_RO(fp,fn); if (fp != NULL) { if (count > 0) { diff --git a/openglcanvas.h b/openglcanvas.h index 522b81d6a41a84357c48f3e02a1d34cba7a283b7..42bf36454dec141adcdb9eb0b03919241678c2b8 100644 --- a/openglcanvas.h +++ b/openglcanvas.h @@ -28,30 +28,14 @@ #include #include #include -#ifdef _WIN32 - #include -#else - #include // for getcwd, getpwuid, getuid -#endif -#include "chronos.h" - -#ifndef _MSC_VER -extern "C" { -#include -#include -#include -} -#endif -#include +#include "chronos.h" -enum FileType{ - PNM, - JPEG, - UNKNOWN -}; +#include "image_read.h" -class OpenGLCanvas : public QGLWidget +class OpenGLCanvas: + public QGLWidget, + public FileRead { Q_OBJECT public: @@ -68,12 +52,7 @@ protected: void load_sphere_mesh(float *positions, int m, int n); float calculate_extent(float fov_rads); void define_triangle_indices(unsigned int * indices, int m, int n); -#ifndef _MSC_VER - int pnmGetTextureSize(const char *const progname, const char *texturePath); - void pnmReadTextureBytes(const char *const progname, const char *texturePath,unsigned char *textureBytes,int *outImageWidth,int *outImageHeight); -#endif - int jpgGetTextureSize(const char *texturePath); - void jpgReadTextureBytes(const char *texturePath,unsigned char *textureBytes,int *outImageWidth,int *outImageHeight); + char *textFileRead(char *fn); void setShaders(); void mousePressEvent(QMouseEvent *event); @@ -126,7 +105,7 @@ private: char* shader_dir; char* input_image_file; - // input image size (determined automatically) + // input image size int image_size_x; int image_size_y; diff --git a/pano_interface_1.pro b/pano_interface_1.pro index 49afce79839456bccba58e1d00e7d299f6bbba9b..aff4177297fd03a4785e098f31bb0dca00a7dbde 100644 --- a/pano_interface_1.pro +++ b/pano_interface_1.pro @@ -65,10 +65,13 @@ TEMPLATE = app SOURCES += main.cpp\ panowindow1.cpp \ openglcanvas.cpp \ - chronos.cpp + chronos.cpp \ + image_read.cpp HEADERS += panowindow1.h \ openglcanvas.h \ - chronos.h + chronos.h \ + image_read.h \ + files.h FORMS += panowindow1.ui