Почему текстура не загружается?

При запуске программы окно открывается на несколько секунд, а затем закрывается. В консоли выводится следующее сообщение: <br/> <pre><code>"D:\Programming Projects\CPP Projects\Minecraft\cmake-build-debug\source\Minecraft.exe"
Opening file: D:/Programming Projects/CPP Projects/Minecraft/resources/textures/test.png
Error reading PNG info

Process finished with exit code -1073741819 (0xC0000005)</code></pre> <br/> <br/> Из консольного вывода я смог определить строку, где происходит сбой программы: <code class="cpp">png_read_info(png_ptr, info_ptr);</code> в функции, ответственной за загрузку PNG. Однако я не могу понять, как исправить эту ошибку. <br/> Ниже приведен код функции загрузки PNG: <pre><code class="cpp">int Loader::loadPng(const char* fileName, int* width, int* height) {
        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;

        std::cout &lt;&lt; "Opening file: " &lt;&lt; fileName &lt;&lt; std::endl;
        f = fopen(fileName, "rb");
        if (!f) {
            std::cerr &lt;&lt; "Error opening file: " &lt;&lt; fileName &lt;&lt; std::endl;
            return 0;
        }

        fread(header, 1, 8, f);
        is_png = !png_sig_cmp(header, 0, 8);
        if (!is_png) {
            fclose(f);
            std::cerr &lt;&lt; "File is not recognized as a PNG file" &lt;&lt; std::endl;
            return 0;
        }

        png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
        if (!png_ptr) {
            fclose(f);
            std::cerr &lt;&lt; "png_create_read_struct failed" &lt;&
  • 25 октября 2024 г. 12:23
Ответы на вопрос 1
Проблема, с которой вы столкнулись, скорее всего, связана с некорректным чтением файла или с ошибками в работе с библиотекой libpng. Давайте разберем ваш код и укажем на некоторые возможные причины проблемы и рекомендации по исправлению.

### Возможные причины проблемы:

1. **Некорректный файл**:
   - Убедитесь, что файл `test.png` существует по указанному пути `D:/Programming Projects/CPP Projects/Minecraft/resources/textures/test.png` и что он действительно является файлом PNG. Если файл поврежден или имеет неверный формат, функция `png_read_info()` может выдавать ошибку.

2. **Закрытие файла**:
   - Вы закрываете файл `f` раньше, чем вызываете `png_read_info()`, если файл не был распознан как PNG. В этом случае файл остается открытым, и вы не сможете читать его позже. Попробуйте перенести закрытие файла в более поздний момент, либо используйте конструкцию, которая гарантирует закрытие файла в конце.

3. **Обработка библиотек**:
   - Убедитесь, что вы правильно инициализируете все структуры, которые требуются для работы с libpng. Например, вы не указываете, что делать в случае ошибки при вызове `png_create_info_struct()`. Вы можете создать `info_ptr` и `end_info`, после создания `png_ptr`, а также должны убедиться, что освобождаете все ресурсы в случае ошибки.

### Рекомендации по исправлению кода:

Вот возможный улучшенный вариант вашей функции:

```cpp
int Loader::loadPng(const char* fileName, int* width, int* height) {
    FILE *f;
    png_structp png_ptr;
    png_infop info_ptr;
    int is_png;
    png_uint_32 t_width, t_height;
    png_byte header[8];

    std::cout << "Opening file: " << fileName << std::endl;
    f = fopen(fileName, "rb");
    if (!f) {
        std::cerr << "Error opening file: " << fileName << std::endl;
        return 0;
    }

    fread(header, 1, 8, f);
    is_png = !png_sig_cmp(header, 0, 8);
    if (!is_png) {
        fclose(f);
        std::cerr << "File is not recognized as a PNG file" << std::endl;
        return 0;
    }

    // Инициализация структур
    png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    if (!png_ptr) {
        fclose(f);
        std::cerr << "png_create_read_struct failed" << std::endl;
        return 0;
    }

    info_ptr = png_create_info_struct(png_ptr);
    if (!info_ptr) {
        png_destroy_read_struct(&png_ptr, NULL, NULL);
        fclose(f);
        std::cerr << "png_create_info_struct failed" << std::endl;
        return 0;
    }

    if (setjmp(png_jmpbuf(png_ptr))) {
        png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
        fclose(f);
        std::cerr << "Error during png_read_info" << std::endl;
        return 0;
    }

    png_init_io(png_ptr, f);
    png_set_sig_bytes(png_ptr, 8);
    png_read_info(png_ptr, info_ptr);

    // ... (здесь вы можете добавлять код для дальнейшей обработки)

    fclose(f); // Закрываем файл только здесь, после всех операций

    return 1; // Например, возвращаем 1 при успешной загрузке
}
```

### Заключение

Передавая управление в библиотеку libpng, важно правильно обрабатывать ошибки и освобождать ресурсы в случае их возникновения. Также, предоставьте визуальное подтверждение текста об ошибках, что упрощает их диагностику.

Убедитесь, что ваша библиотека libpng правильно настроена и совместима с вашим проектом. Если проблема сохраняется, попробуйте открыть файл PNG в графическом редакторе, чтобы убедиться, что он не поврежден.
Похожие вопросы