libpng 在 png_read_info() 上崩溃
libpng crashes on png_read_info()
我正在尝试在vs2013中使用libpng 1.2.10读取png文件。我下载了最新的 zlib 并编译了 pnglib,效果很好。现在我正在尝试加载一个文件:
int *w = &width;
int *h = &height;
const char* name = file.c_str();
FILE *png_file = fopen(name, "rb");
if (!png_file)
{
std::cerr << "Could not open " + file << std::endl;
return;
}
unsigned char header[PNG_SIG_BYTES];
fread(header, 1, PNG_SIG_BYTES, png_file);
if (png_sig_cmp(header, 0, PNG_SIG_BYTES))
{
std::cerr << "PNG signature fail " + file << std::endl;
return;
}
png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if(png_ptr == NULL)
{
std::cerr << "PNG read fail " + file << std::endl;
return;
}
png_infop info_ptr = png_create_info_struct(png_ptr);
if(!info_ptr)
{
std::cerr << "PNG info fail " + file << std::endl;
return;
}
png_infop end_info = png_create_info_struct(png_ptr);
if(!end_info)
{
std::cerr << "PNG info end fail " + file << std::endl;
return;
}
if (setjmp(png_jmpbuf(png_ptr)))
{
std::cerr << "PNG setjmp fail " + file << std::endl;
return;
}
png_init_io(png_ptr, png_file);
png_set_sig_bytes(png_ptr, PNG_SIG_BYTES);
png_read_info(png_ptr, info_ptr);
*w = png_get_image_width(png_ptr, info_ptr);
*h = png_get_image_height(png_ptr, info_ptr);
png_uint_32 bit_depth, color_type;
bit_depth = png_get_bit_depth(png_ptr, info_ptr);
color_type = png_get_color_type(png_ptr, info_ptr);
if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
{
std::cerr << "Grayscale PNG not supported " + file << std::endl;
return;
}
if (bit_depth == 16)
png_set_strip_16(png_ptr);
if (color_type == PNG_COLOR_TYPE_PALETTE)
png_set_palette_to_rgb(png_ptr);
else if (color_type == PNG_COLOR_TYPE_GRAY ||
color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
{
png_set_gray_to_rgb(png_ptr);
}
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
png_set_tRNS_to_alpha(png_ptr);
else
png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
png_read_update_info(png_ptr, info_ptr);
png_uint_32 rowbytes = png_get_rowbytes(png_ptr, info_ptr);
png_uint_32 numbytes = rowbytes*(height);
png_byte* pixels = (png_byte*)malloc(numbytes);
png_byte** row_ptrs = (png_byte**)malloc((height)* sizeof(png_byte*));
int i;
for (i = 0; i<height; i++)
row_ptrs[i] = pixels + (height - 1 - i)*rowbytes;
png_read_image(png_ptr, row_ptrs);
free(row_ptrs);
png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
fclose(png_file);
//return (char *)pixels;
Create(*w, *h, 4, pixels, GL_UNSIGNED_BYTE);
不幸的是,我得到了
在 SimpleShader.exe 中0x77D78E19 (ntdll.dll) 处未处理的异常: 0xC0000005:访问冲突写入位置0x00000014。
在线
png_read_info(png_ptr, info_ptr);
具体来说,错误发生在这里:
#ifdef PNG_STDIO_SUPPORTED
/* This is the function that does the actual reading of data. If you are
* not reading from a standard C stream, you should create a replacement
* read_data function and use it at run time with png_set_read_fn(), rather
* than changing the library.
*/
void PNGCBAPI
png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
{
png_size_t check;
if (png_ptr == NULL)
return;
/* fread() returns 0 on error, so it is OK to store this in a png_size_t
* instead of an int, which is what fread() actually returns.
*/
check = fread(data, 1, length, png_voidcast(png_FILE_p, png_ptr->io_ptr)); // <---------- ERROR HERE
if (check != length)
png_error(png_ptr, "Read Error");
}
#endif
可能是什么问题?
编辑:好的,当我在发布模式下编译libpng和我的项目时,它不会崩溃。我需要在调试模式下运行我的项目...
这是由于 libpng 和项目之间的编译器设置不匹配造成的。特别是运行时库设置,在 libpng 和项目中都必须是多线程 DLL (/MD)。自述文件指出:
如果不使用 Visual Studio 默认值,则仍必须生成应用程序 使用默认运行时选项 (/MD)。 如果由于某种原因不是,那么您的 一旦 libpng 尝试读取.dll应用程序就会在 libpng16 中崩溃 从您传入的文件句柄。
避免崩溃并保留调试可能性的最简单方法是复制项目中的"发布"配置并更改一些属性,以便可以在 Visual Studio 中轻松调试。具体操作方法如下:
- 在项目上单击 RMB ->属性 -> 配置管理器 ->展开活动解决方案配置并单击 。选择新名称并从"发布"中复制设置。
- 现在,在项目设置中,选择新创建的配置并更改以下属性:
- C/C++ -> 常规 -> 调试信息格式:用于编辑并继续的程序数据库 (/ZI)
- C/C++ -> 优化 -> 优化:禁用 (/od),全程序优化:否
- 这就是所有必要的。您还可以禁用链接器优化(引用和 COMDAT 折叠)、启用最小重新生成等。
就是这样,祝你好运!
相关文章:
- 当回溯以零开始时,如何调试崩溃
- 内联映射初始化的动态atexit析构函数崩溃
- 执行函数时导致崩溃的变量
- 程序崩溃并显示"std::out_of_range"错误
- CoInitialize()在单独的线程上崩溃而不返回
- 使用调试/崩溃报告将应用程序部署到客户端
- 为什么所有C++编译器都会崩溃或挂起此代码
- 为什么lambda在clang上崩溃而不是在gcc上崩溃
- 为什么我的多线程作业队列崩溃
- ExtractIconEx:可以工作,但偶尔会崩溃
- 为什么引用传递会导致此崩溃(C++)
- 试图创建流或fopen时程序崩溃
- 类对象数组的问题会导致崩溃
- 排序时无法执行交换操作.我做的时候它会崩溃.为什么
- 为什么要增加导致崩溃的指针
- 在虚幻引擎中删除NXOpen对象时崩溃
- 为什么它只打印双链接列表的第一个值,而我的程序却崩溃了
- 应用程序崩溃并显示"symbol _ZdlPvm, version Qt_5 not defined in file libQt5Core.so.5 with link time reference"
- 为什么我的程序在构造函数中使用read时会崩溃?
- 对指针向量进行排序一次,然后崩溃并"unable to read memory"