Commit 80e0504b authored by Luis Penaranda's avatar Luis Penaranda
Browse files

improved support for PNG images

parent 4c79db4c
Loading
Loading
Loading
Loading
+47 −19
Original line number Diff line number Diff line
@@ -116,9 +116,9 @@ unsigned char *FileRead::pngRead(const char *texturePath,
    }
    // 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);
                                               NULL,
                                               NULL,
                                               NULL);
    if(!png_ptr){
        fprintf(stderr,"error reading %s\n",texturePath);
        exit(-1);
@@ -139,40 +139,68 @@ unsigned char *FileRead::pngRead(const char *texturePath,
    *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);
    png_byte bit_depth=png_get_bit_depth(png_ptr,info_ptr);
    if(bit_depth==16)
        png_set_strip_16(png_ptr);
    if(bit_depth<8)
        png_set_expand_gray_1_2_4_to_8(png_ptr);
    if(color_type==PNG_COLOR_TYPE_GRAY||color_type==PNG_COLOR_TYPE_GRAY_ALPHA)
        png_set_gray_to_rgb(png_ptr);
    if(color_type==PNG_COLOR_TYPE_PALETTE){
        png_set_palette_to_rgb(png_ptr);
        // TODO: Read the transparency values for indexed images;
        // currently, they are ignored by stripping the alpha information.
        png_set_strip_alpha(png_ptr);
    }
    // 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*
                                   3* // RGB
                                   sizeof(unsigned char));
    // read the contents of the file
    if(setjmp(png_jmpbuf(png_ptr))){
        fprintf(stderr,"error reading %s\n",texturePath);
        exit(-1);
    }
    // TODO: we can avoid writing in row_pointers[] and later copying to
    // the texture.
    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];
            }
        }
    switch(color_type){
    case PNG_COLOR_TYPE_GRAY:
    case PNG_COLOR_TYPE_PALETTE:
    case PNG_COLOR_TYPE_RGB:
        // RGB: copy directly RGB bits to the texture.
        for(int row=0;row<(*outImageHeight);++row)
            for(int j=0;j<(*outImageWidth);++j)
                for(int k=0;k<3;++k)
                        textureBytes[row*(*outImageWidth)*3+j*3+k]=
                            row_pointers[(*outImageHeight)-row-1][j*3+k];
        break;
    case PNG_COLOR_TYPE_GRAY_ALPHA:
    case PNG_COLOR_TYPE_RGB_ALPHA:
        // RGBA: multiply each one of the three first bytes (channels R, G
        // and B), by the alpha (the fourth byte).
        for(int row=0;row<(*outImageHeight);++row)
            for(int j=0;j<(*outImageWidth);++j)
                for(int k=0;k<3;++k)
                        textureBytes[row*(*outImageWidth)*3+j*3+k]=
                            (double)
                            row_pointers[(*outImageHeight)-row-1][j*4+k]*
                            row_pointers[(*outImageHeight)-row-1][j*4+3]/
                            255;
        break;
    default:
        fprintf(stderr,"%s: unrecognized PNG type\n",texturePath);
        exit(-1);
    }
    png_read_end(png_ptr,NULL);
    png_destroy_read_struct(&png_ptr,&info_ptr,NULL);
    for(int row=0;row<(*outImageHeight);++row)
            free(row_pointers[row]);
    free(row_pointers);

input_images/grid.png

0 → 100644
+1.47 KiB
Loading image diff...

input_images/grid.pnm

deleted100644 → 0
−5.72 MiB

File deleted.