我正在使用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 回答
假设:此代码假定每个图像都是24位/像素RGB格式 .
如果您读取32位/像素RGBA图像或48位/像素RGB图像,则分配
不会为每条扫描线分配足够的字节数 .
C是不安全的语言,当读取这些太短的数组时,缓冲区溢出会使堆数据结构丢弃,这可能不会触发症状,直到你尝试释放某些东西 .
此外,看起来这个代码忘记在成功的情况下释放数组,或者
data_
是一个用于将图像保存在内存中的实例变量?