首页 文章

在读取尺寸大于200x200像素的png图像时,在0x77662D37(ntdll.dll)处出现未处理的异常[关闭]

提问于
浏览
0

我正在使用libpng来读取Visual C中的png文件 . 在读取尺寸为195x195px或更小的图像时,该程序可正常工作,但在更高尺寸时会崩溃 .

这是错误消息:

myprog.exe中0x77662D37(ntdll.dll)的第一次机会异常:0xC0000005:访问冲突读取位置0xB4BFDDFF . myprog.exe中0x77662D37(ntdll.dll)的未处理异常:0xC0000005:访问冲突读取位置0xB4BFDDFF .

这里是代码:

bool PngImage::load(void)
{
    png_structp pngPtr(NULL);
    png_infop infoPtr(NULL);
    FILE* fp(NULL);

    png_uint_32 w = 0, h = 0;
    int bit_depth, color_type, interlace_type;

    fp = fopen(fileName_.c_str(), "rb");
    if (!fp)
        return false;

    pngPtr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    if (!pngPtr)
    {
        fclose(fp);
        return false;
    }

    infoPtr = png_create_info_struct(pngPtr);
    if (!infoPtr)
    {
        fclose(fp);
        png_destroy_read_struct(&pngPtr, png_infopp_NULL, png_infopp_NULL);
        return false;
    }

    if (setjmp(png_jmpbuf(pngPtr)))
    {
        png_destroy_read_struct(&pngPtr, &infoPtr, png_infopp_NULL);
        fclose(fp);
        return false;
    }

    png_init_io(pngPtr, fp);

    if (setjmp(png_jmpbuf(pngPtr)))
    {
        png_destroy_read_struct(&pngPtr, &infoPtr, png_infopp_NULL);
        fclose(fp);
        return false;
    }

    png_read_info(pngPtr, infoPtr);

    png_get_IHDR(pngPtr, infoPtr, &w, &h,
        &bit_depth, &color_type, &interlace_type,
        int_p_NULL, int_p_NULL);

    if (setjmp(png_jmpbuf(pngPtr)))
    {
        png_destroy_read_struct(&pngPtr, &infoPtr, png_infopp_NULL);
        fclose(fp);
        return false;
    }

    width_ = static_cast<size_t>(w);
    height_ = static_cast<size_t>(h);

    data_ = new png_bytep[height_];
    for (size_t i = 0; i < height_; ++i)
        data_[i] = new png_byte[width_ * BYTE_PER_PIXEL];

    png_read_image(pngPtr, data_);

    if (setjmp(png_jmpbuf(pngPtr)))
    {
        png_destroy_read_struct(&pngPtr, &infoPtr, png_infopp_NULL);
        fclose(fp);
        for (size_t i = 0; i < height_; ++i)
            delete[] data_[i];
        delete[] data_;
        data_ = NULL;
        width_ = height_ = 0;
        return false;
    }

    png_read_end(pngPtr, infoPtr);

    png_destroy_read_struct(&pngPtr, &infoPtr, png_infopp_NULL);

    fclose(fp);

    return true;
}

常数的值:

const size_t BYTE_PER_PIXEL = 3;
const size_t RED_OFFSET = 0;
const size_t GREEN_OFFSET = 1;
const size_t BLUE_OFFSET = 2;
const png_byte BIT_DEPTH = 8;

代码似乎停在png_destroy_read_struct(&pngPtr,&infoPtr,png_infopp_NULL);在fclose(fp)之前 .

可能是我得到未处理异常的原因是什么?希望你能帮忙解决这个问题 . 先感谢您 .

PS:我对libpng并不熟悉

1 回答

  • 0

    假设:此代码假定每个图像都是24位/像素RGB格式 .

    如果您读取32位/像素RGBA图像或48位/像素RGB图像,则分配

    data_ [i] = new png_byte [width_ * BYTE_PER_PIXEL];

    不会为每条扫描线分配足够的字节数 .

    C是不安全的语言,当读取这些太短的数组时,缓冲区溢出会使堆数据结构丢弃,这可能不会触发症状,直到你尝试释放某些东西 .

    此外,看起来这个代码忘记在成功的情况下释放数组,或者 data_ 是一个用于将图像保存在内存中的实例变量?

相关问题