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

preliminary support for reading PNG images

parent 42d772a0
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -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.

+99 −8
Original line number Diff line number Diff line
#include "image_read.h"
#include <cstdio>   // for fread
#include "files.h"
#include <cstring>
#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");
@@ -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<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
unsigned char *FileRead::pnmRead(const char * const progname,
                                 const char *texturePath,
+5 −3
Original line number Diff line number Diff line
@@ -2,6 +2,8 @@
#define IMAGE_READ_H

#include <utility>
#include <jpeglib.h>
#include <png.h>

#ifndef _MSC_VER
extern "C" {
@@ -14,11 +16,10 @@ extern "C" {
  #endif
#endif

#include <jpeglib.h>

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
+3 −3
Original line number Diff line number Diff line
@@ -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