Commit 42d772a0 authored by Luis Penaranda's avatar Luis Penaranda

abstracted image reading in a new class

parent f96925de
#ifndef FILES_H
#define FILES_H
#ifdef _MSC_VER
#include <io.h>
#include <direct.h>
#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 <cstdio> // for fopen and fclose
#include <unistd.h> // 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
#include "image_read.h"
#include "files.h"
#include <cstring>
// 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<inpam.depth;++plane) {
textureBytes[((*outImageHeight)-row-1)*3*(*outImageWidth)+3*column+plane]=
tuplerow[column][plane];
}
}
}
pnm_freepamrow(tuplerow);
pm_close(in_file);
return textureBytes;
}
#endif
#ifndef IMAGE_READ_H
#define IMAGE_READ_H
#include <utility>
#ifndef _MSC_VER
extern "C" {
#include <ppm.h>
#include <pm.h>
#include <pam.h>
}
#ifndef _MSC_VER
#define PROGNAME "pano_interface"
#endif
#endif
#include <jpeglib.h>
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
......@@ -11,34 +11,10 @@
#else
#include <pwd.h> // for getpwuid
#endif
#include <cstdio> // for fopen, fclose, getc
#include <cstdio> // for getc
#include <cstring>
#ifdef _MSC_VER
#include <direct.h>
#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_scanline<cinfo.output_height){
--scanline;
jpeg_read_scanlines(&cinfo,row_pointer,1);
for(int i=0;i<image_size_x*depth;++i){
textureBytes[scanline*image_size_x*depth+i]=row_pointer[0][i];
}
}
*outImageWidth=cinfo.output_width;
*outImageHeight=cinfo.output_height;
fclose(in_file);
jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);
}
void OpenGLCanvas::resizeGL(int w, int h){
if(w>h)
......@@ -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) {
......
......@@ -28,30 +28,14 @@
#include <QFile>
#include <QFileDialog>
#include <fcntl.h>
#ifdef _WIN32
#include <io.h>
#else
#include <unistd.h> // for getcwd, getpwuid, getuid
#endif
#include "chronos.h"
#ifndef _MSC_VER
extern "C" {
#include <ppm.h>
#include <pm.h>
#include <pam.h>
}
#endif
#include <jpeglib.h>
#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;
......
......@@ -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
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