libpng 在 png_read_info() 上崩溃

2024-01-09

我正在尝试在 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 和我的项目时,它不会崩溃。我需要在调试模式下运行我的项目......


This is caused by a mismatch in the compiler settings between libpng and your project. In particular, the Runtime Library setting, that has to be Multi-threaded DLL (/MD) in both libpng and your project. The readme states:

如果您不使用 Visual Studio 默认设置,您的应用程序仍必须构建 使用默认运行时选项 (/MD)。如果由于某种原因,它不是你的 当 libpng 尝试读取时,应用程序将在 libpng16.dll 内崩溃 从您传入的文件句柄。

避免崩溃并保留调试可能性的最简单方法是复制项目中的“Release”配置并更改一些属性,以便您可以在 Visual Studio 中轻松调试。操作方法如下:

  1. 在项目上单击 RMB -> 属性 -> 配置管理器 -> 展开活动解决方案配置并单击 。选择一个新名称并从发布中复制设置。
  2. Now in the project settings, pick the newly created configuration and change the following properties:
    • C/C++ -> 常规 ->调试信息格式:用于编辑并继续的程序数据库 (/ZI)
    • C/C++ -> 优化 ->优化:禁用(/Od),整体程序优化: No
    • 这就是所需要的一切。您还可以禁用链接器优化(引用和 COMDAT 折叠)、启用最小重建等。

就是这样,祝你好运!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

libpng 在 png_read_info() 上崩溃 的相关文章

  • WindowsError:[错误 126] 使用 ctypes 加载操作系统时

    python代码无法在Windows 7平台上运行 def libSO lib ctypes cdll LoadLibrary ConsoleApplication2 so lib cfoo2 1 3 当我尝试运行它时 得到来自python
  • 更新面板工作速度非常慢

    我正在编写一个用户可以注册的应用程序 注册时 可以选择多个选项 并根据这些注册字段可见或不可见以及是否必需 我想出了一个想法 所有字段都将位于 updatePanel 中 当用户更改注册选项时 我将在服务器端设置这些字段的可见性 它可以工作
  • 为什么这个 Web api 控制器不并发?

    我有一个 Web API 控制器 里面有以下方法 public string Tester Thread Sleep 2000 return OK 当我调用它 10 次 使用 Fiddler 时 我预计所有 10 次调用都会在大约 2 秒后
  • 强制初始化模板类的静态数据成员

    关于模板类的静态数据成员未初始化存在一些问题 不幸的是 这些都没有能够帮助我解决我的具体问题的答案 我有一个模板类 它有一个静态数据成员 必须为特定类型显式实例化 即必须专门化 如果不是这种情况 使用不同的模板函数应该会导致链接器错误 这是
  • 在 VS 中运行时如何查看 C# 控制台程序的输出?

    我刚刚编写了一个名为 helloworld 的聪明程序 它是一个 C NET 4 5 控制台应用程序 在扭曲的嵌套逻辑迷宫深处 使用了 Console WriteLine 当我在命令行运行它时 它会运行并且我会看到输出 我可以执行其他命令并
  • 如何递归取消引用指针(C++03)?

    我正在尝试在 C 中递归地取消引用指针 如果传递一个对象 那就是not一个指针 这包括智能指针 我只想返回对象本身 如果可能的话通过引用返回 我有这个代码 template
  • 如果输入被重定向则执行操作

    我想知道如果我的输入被重定向 我应该如何在 C 程序中执行操作 例如 假设我有已编译的程序 prog 并且我将输入 input txt 重定向到它 我这样做 prog lt input txt 我如何在代码中检测到这一点 一般来说 您无法判
  • 模板外部链接?谁能解释一下吗?

    模板名称具有链接 3 5 非成员函数模板可以有内部链接 任何其他模板名称应具有外部链接 从具有内部链接的模板生成的实体与在其他翻译单元中生成的所有实体不同 我知道使用关键字的外部链接 extern C EX extern C templat
  • 在 C# 中为父窗体中的子窗体控件添加事件处理程序

    我有两种形式 一种是带有按钮和文本框的父表单 单击该按钮时 将打开一个对话框 该子窗体又包含一个文本框和一个按钮 现在我想要的是 每当子表单文本框中的文本更改时 父表单文本框中的文本会自动更改 为了获得这个 我所做的是 Form3 f3 n
  • memcpy/memmove 到联合成员,这是否设置“活动”成员?

    重要说明 一些评论者似乎认为我是从工会抄袭的 仔细看memcpy 它从普通旧地址复制uint32 t 它不包含在联合中 另外 我正在复制 通过memcpy 到工会的特定成员 u a16 or u x in a union 不直接到整个联盟本
  • C++ - 多维数组

    处理多维数组时 是否可以为数组分配两种不同的变量类型 例如你有数组int example i j 有可能吗i and j是两种完全不同的变量类型 例如 int 和 string 听起来您正在寻找 std vector
  • Oauth2中如何同时撤销RefreshToken和使AccessToken失效

    我正在使用 Owin Oauth2 授权和资源服务器相同 开发单页面应用程序 AngularJS Net MVC Json Rest API 的身份验证流程 我选择了 Bearer Token 路由而不是传统的 cookie session
  • 比较:接口方法、虚方法、抽象方法

    它们各自的优点和缺点是什么 接口方法 虚拟方法 抽象方法 什么时候应该选择什么 做出这一决定时应牢记哪些要点 虚拟和抽象几乎是一样的 虚方法在基类中有一个实现 可以选择重写 而抽象方法则没有 并且must在子类中被覆盖 否则它们是相同的 在
  • C++ 对象用 new 创建,用 free() 销毁;这有多糟糕?

    我正在修改一个相对较大的 C 程序 不幸的是 并不总是清楚我之前的人使用的是 C 还是 C 语法 这是在一所大学的电气工程系 我们 EE 总是想用 C 来做所有事情 不幸的是 在这种情况下 人们实际上可以逃脱惩罚 但是 如果有人创建一个对象
  • 使动态创建的链接标签在 Winforms 中可点击

    我正在制作一个程序 允许用户单击由动态链接标签创建的公司名称 在我想知道如何做到这一点之前 我从未在 C 中使用过链接标签 可为特定用户生成的业务数量各不相同 因此每个用户的链接标签数量并不相同 然后我想捕获业务 ID 以进行 Json 调
  • Visual Studio 2015:v120 与 v140?

    仅供参考 Win10 x64 我今天开始尝试 Visual Studio 2015 在弄清楚如何运行 C C 部分后 我尝试加载一个大型个人项目 该项目使用非官方的glsdk http glsdk sourceforge net docs
  • 如何解压 msgpack 文件?

    我正在将 msgpack 编码的数据写入文件 在编写时 我只是使用 C API 的 fbuffer 如 我为示例删除了所有错误处理 FILE fp fopen filename ab msgpack packer pk msgpack pa
  • C++:为什么 numeric_limits 对它不知道的类型起作用?

    我创建了自己的类型 没有任何比较器 也没有专门化std numeric limits 尽管如此 由于某种原因 std numeric limits
  • EntityFramework 6.0.0.0 读取数据,但不插入

    我创建了一个基于服务的数据库 folderName gt Add New Item gt Data gt Service based Database文件到 WPF 应用程序中 然后我用过Database First方法并创建了Person
  • 为什么空循环使用如此多的处理器时间?

    如果我的代码中有一个空的 while 循环 例如 while true 它将把处理器的使用率提高到大约 25 但是 如果我执行以下操作 while true Sleep 1 它只会使用大约1 那么这是为什么呢 更新 感谢所有精彩的回复 但我

随机推荐

  • SQL 中纪元转换为日期时间

    我提供了一个 SQL 函数 可以将纪元转换为日期时间 这个sql函数的问题不起作用适用于 1970 年 1 月 3 日之前的日期 有没有人有任何想法可以使其适用于 1970 年以内的日期 DECLARE total bigint if gr
  • 如何使用 QML 创建启动屏幕

    我正在尝试使用 QT 开发 Android 应用程序 我想在应用程序启动时显示启动屏幕 启动画面将停留 2 秒钟 然后将显示应用程序的主页 为此 我创建了 2 个 qml 文件 启动画面 qml import QtQuick 2 9 imp
  • ImageMagickError 无法读取字体“(null)”:“(null)”

    我在生产服务器 运行 ImageMagick Rmagick 等的 Ubuntu 上遇到此错误已经有一段时间了 从谷歌搜索看来 似乎找不到合适的字体来使用 这需要在 sudo nano usr lib ImageMagick 6 3 7 c
  • Connect 会话中间件签名 cookie 如何工作?

    我想了解 connect sid cookie 在 Connect Node js 框架中如何工作 我注意到它们的格式如下 s hash signature 我不明白当哈希足以用于从内存存储或 Redis 存储访问会话数据时如何使用签名 另
  • Azure 密钥保管库:访问被拒绝

    我有以下代码用于从 Azure 密钥保管库获取机密 public static async Task
  • 与数据库无关的应用程序的数据库设计

    我必须考虑什么在数据库设计中对于一个新的应用程序来说 哪些应该能够支持最常见的关系数据库系统 SQL Server MySQL Oracle PostgreSQL 值得付出努力吗 有哪些陷阱 简而言之 答案是坚持标准或接近标准实现的功能 更
  • 缓存过期控制与上次修改

    在阿帕奇的mod expires模块 有Expires具有两个基准时间段的指令 access and 修改 ExpiresByType text html access plus 30 days 可以理解 这意味着缓存将在 30 天后请求新
  • 如何在 PHP 中将指数转换为小数

    我有一个像这样的字符串 9 018E 14 现在我想将其转换为正常的十进制数 我的极客伙伴 http www mygeekpal com how to convert exponentials to decimals in php 有一篇关
  • MySQL 连接器、流式结果集和批量获取

    我正在浏览 MySQL Connector 5 1 24 源代码 我注意到该方法中有一些不寻常的地方StatementImpl createStreamingResultSet javadoc 说 我们仅在结果集是只进 只读和 获取大小已设
  • 如何在 iPhone 上使用 Quartz/Core Graphics 显示国际口音

    我已经本地化了一个适用于 iPhone 的应用程序 毫不奇怪 本地化包括一些口音 触摸卡片进行选择 然后触摸 出价 Touchez les cartes pour les 选择者 puis touchez 守财奴 这些在高级的东西中工作得很
  • 将 UTC 纪元转换为本地日期

    我已经为此奋斗了一段时间了 我正在尝试将纪元转换为日期对象 该纪元以 UTC 格式发送给我 每当你经过new Date 一个纪元 它假设它是本地纪元 我尝试创建一个 UTC 对象 然后使用setTime 将其调整到正确的纪元 但似乎唯一有用
  • 在 R 中创建表达式树

    中的替代函数R以可以解析的树的形式创建一个语言对象 如何使用 list 从头开始 创建树 然后将其交给 eval substitute gives a tree representation of the expression a 1 b
  • 如何在 ASP.NET 3.5 中对每个 http 请求进行缓存

    我们使用 ASP NET 3 5 基于控件的方法 并且只需要特定于一个 http 请求的存储 使用会话 id 中的键的线程特定缓存将不起作用 因为线程应该被池化 因此我有机会在缓存中获得来自某些先前请求的数据 这在我的情况下是不可取的 我总
  • 在python中组合两个循环

    假设有两个多边形 p1 和 p2 其中 p2 完全在 p1 内部 p1 0 10 10 10 10 0 0 0 p2 2 6 6 6 6 2 2 2 degree of contact 0 xyarrays p1 p2 p1 degree
  • asp.net 中的 GridView 标题文本

    我想使用 Design 更改 gridview 的标题文本
  • Terminal.app 可以遵循 ANSI 转义码吗?

    我注意到 随着TERM环境变量设置为xterm or xterm 256colorMac OS X 的 Terminal app 实用程序尊重大多数 ANSI 转义码 至少当这些转义码涉及更改文本颜色时 例如 echo e 033 0 31
  • 我可以使用 C# 在 Sharepoint 2010 中为计算字段创建自己的公式吗

    我想使用 Visual Studio 2010 以 C 语言为 Sharepoint 2010 创建一个以编程方式计算的字段 有没有办法设置一个公式来调用我自己的函数并将结果返回到字段 我的场景 假设我想创建一个始终返回其他两个字段之间的总
  • 发件人证书在签名验证之前已过期

    我正在开发一个关于 Java 中的证书和数字签名的项目 但我无法理解以下情况 文件发送者和接收者的证书在创建签名时有效 但当接收者收到文件时 发送者的证书已过期 这种情况是否有效 接收者可以正常验证签名 还是不能 还有一个问题 不可否认密钥
  • GLMakie 图 x 轴的量化失真。为什么?

    我使用创建一个简单的图GLMakie GLMakie scatter range 3e 9 1e 3 3e 9 1e 3 100 range 1 100 100 结果如下 看起来 x 轴被严重量化了 这Plots包可以很好地处理相同的命令
  • libpng 在 png_read_info() 上崩溃

    我正在尝试在 vs2013 中使用 libpng 1 2 10 读取 png 文件 我下载了最新的zlib并编译了pnglib 运行良好 现在我正在尝试加载一个文件 int w width int h height const char n