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

abstracted image reading in a new class

parent f96925de
Loading
Loading
Loading
Loading

files.h

0 → 100644
+29 −0
Original line number Diff line number Diff line
#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

image_read.cpp

0 → 100644
+131 −0
Original line number Diff line number Diff line
#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

image_read.h

0 → 100644
+37 −0
Original line number Diff line number Diff line
#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
+12 −192
Original line number Diff line number Diff line
@@ -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) {
+7 −28
Original line number Diff line number Diff line
@@ -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;

Loading