P
P
Pavel Matveev2020-05-27 19:34:50
C++ / C#
Pavel Matveev, 2020-05-27 19:34:50

The function of reading a .png image and converting it to an OpenGL texture does not work. What's wrong?

The function to read a .png image and convert it to an OpenGL texture does not work,
returning null at runtime.
Function code:

int _png_load(const char* file, int* width, int* height) {

    std::cout << file << std::endl;

    FILE* f;
    int is_png, bit_depth, color_type, row_bytes;
    png_infop info_ptr, end_info;
    png_uint_32 t_width, t_height;
    png_byte header[8], * image_data;
    png_bytepp row_pointers;
    png_structp png_ptr;
    GLuint texture;
    int alpha;

    if ((f = fopen(file, "r"))) {
        return 0;
    }
    fread(header, 1, 8, f);
    is_png = !png_sig_cmp(header, 0, 8);
    if (!is_png) {      //Здесь выбрасывает, т.к. файл, якобы, не является .png-файлом.
        fclose(f);
        return 0;
    }
    png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL,
        NULL, NULL);
    if (!png_ptr) {
        fclose(f);
        return 0;
    }
    info_ptr = png_create_info_struct(png_ptr);
    if (!info_ptr) {
        png_destroy_read_struct(&png_ptr, (png_infopp)NULL,
            (png_infopp)NULL);
        fclose(f);
        return 0;
    }
    end_info = png_create_info_struct(png_ptr);
    if (!end_info) {
        png_destroy_read_struct(&png_ptr, (png_infopp)NULL,
            (png_infopp)NULL);
        fclose(f);
        return 0;
    }
    if (setjmp(png_jmpbuf(png_ptr))) {
        png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
        fclose(f);
        return 0;
    }
    png_init_io(png_ptr, f);
    png_set_sig_bytes(png_ptr, 8);
    png_read_info(png_ptr, info_ptr);
    png_get_IHDR(png_ptr, info_ptr, &t_width, &t_height, &bit_depth,
        &color_type, NULL, NULL, NULL);
    *width = t_width;
    *height = t_height;
    png_read_update_info(png_ptr, info_ptr);
    row_bytes = (int)png_get_rowbytes(png_ptr, info_ptr);
   image_data = (png_bytep)malloc(row_bytes * t_height * sizeof(png_byte));
    if (!image_data) {
        png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
        fclose(f);
        return 0;
    }
    row_pointers = (png_bytepp)malloc(t_height * sizeof(png_bytep));
    if (!row_pointers) {
        png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
        free(image_data);
        fclose(f);
        return 0;
    }

    for (unsigned int i = 0; i < t_height; ++i) {
        row_pointers[t_height - 1 - i] = image_data + i * row_bytes;
    }
    png_read_image(png_ptr, row_pointers);

    switch (png_get_color_type(png_ptr, info_ptr)) {
    case PNG_COLOR_TYPE_RGBA:
        alpha = GL_RGBA;
        break;
    case PNG_COLOR_TYPE_RGB:
        alpha = GL_RGB;
        break;
    default:
        printf("Color type %d not supported!\n",
            png_get_color_type(png_ptr, info_ptr));
        png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
        return 0;
    }
    glGenTextures(1, &texture);
    glBindTexture(GL_TEXTURE_2D, texture);
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, t_width, t_height, 0,
        alpha, GL_UNSIGNED_BYTE, (GLvoid*)image_data);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glBindTexture(GL_TEXTURE_2D, 0);

    png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
    free(image_data);
    free(row_pointers);
    fclose(f);
    return texture;
}


There are no build errors other than the fact that fopen() might be an unsafe function.
Visual Studio 2019, MSVC, Release x64.
Libs included by the linker: opengl32, glu32, glew32s, , glfw3, libpng16, libpng16_static.

Answer the question

In order to leave comments, you need to log in

2 answer(s)
P
Pavel Matveev, 2020-05-27
@axe_lankaster13

So, thanks to everyone) I found the error myself:
png_sig_cmp() checks the data read in the "bitwise" mode, i.e. I should have written fopen(file, "rb"), but I wrote fopen(file,"r")

A
Alexander Ananiev, 2020-05-27
@SaNNy32

!png_sig_cmp(header, 0, 8);
Why is there a "!" ?

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question