Libjpeg 错误 - 状态 205 中的不正确调用
Posted
技术标签:
【中文标题】Libjpeg 错误 - 状态 205 中的不正确调用【英文标题】:Libjpeg error - improper call in state 205 【发布时间】:2011-04-30 02:56:57 【问题描述】:我正在使用 libjpeg(Windows Mobile 6.5 上的 C/C++ 编程)来解码来自 IP 摄像机的图像(以 MJPEG 流形式发送),然后再将它们推送到 DirectShow 图形中。
到目前为止,我一直在使用一个函数:接收流、手动解析(以便找到 JPEG 数据的起点和终点)、解码数据(即初始化 libjpeg 结构、读取JPEG 标头,进行实际解码...),最后将其推入图表。这可以正常工作,但为了使事情更流畅和更整洁,我想使用一个函数来接收,它调用另一个函数(后来是一个线程)进行解码/推送。
因此,作为第一步,我不是在找到流中的数据后立即执行所有 JPEG 工作,而是简单地调用另一个函数来负责 JPEG 结构的 init / header 读取/解码/推送。
这是我无法破译的错误:“在状态 205 中对 jpeg 库的不当调用”。
// 为清晰而编辑
目前,我的代码如下所示:
无效接收1() 而(1) if(recvfrom(/* ... */) > 0) /* 解析接收到的 JPEG 开始和结束数据 */ /* 解码 JPEG */ //声明 结构 jpeg_decompress_struct cinfo; 结构 my_error_mgr jerr; // 第一步:分配/初始化 cinfo.err = jpeg_std_error(&jerr.pub); jerr.pub.error_exit = my_error_exit; 如果(setjmp(jerr.setjmp_buffer)) printf("--错误 LIBJPEG\n"); /* 退出并返回错误码 */ // 下一步:继续解码和显示... jpeg_create_decompress(&cinfo); /* ... */我想让我的代码看起来像:
无效接收2() 而(1) if(recvfrom(/* ... */) > 0) /* 解析接收到的 JPEG 开始和结束数据 */ 解码(数据); 诠释解码(字符*数据) /* 解码 JPEG */ //声明 结构 jpeg_decompress_struct cinfo; 结构 my_error_mgr jerr; // 第一步:分配/初始化 cinfo.err = jpeg_std_error(&jerr.pub); jerr.pub.error_exit = my_error_exit; if(setjmp(jerr.setjmp_buffer)) // 这就是“state 205”错误发生的地方 printf("--错误 LIBJPEG\n"); /* 退出并返回错误码 */ // 下一步:继续解码和显示... jpeg_create_decompress(&cinfo); /* ... */ 返回0;任何帮助将不胜感激。非常感谢!
// 编辑
我意识到我在原始帖子中遗漏了很多信息。以下是一些(也许)有用的细节:
我使用的是 VS2008,但由于许多原因,我不使用内置的调试器或仿真器。而是直接在 Windows Mobile 设备上部署和测试 exe 文件,使用自定义的类似 dos 的命令提示符。 libjpeg 最初读取和写入文件,但我使用的补丁(和自定义错误处理程序)能够直接从缓冲区读取数据,而无需打开文件。代码可以在here 找到,它使用了这样定义的“扩展错误处理程序”:typedef struct my_error_mgr * my_error_ptr; 结构 my_error_mgr 结构 jpeg_error_mgr pub; jmp_buf setjmp_buffer; ; 方法(无效)my_error_exit(j_common_ptr cinfo) my_error_ptr myerr = (my_error_ptr) cinfo->err; /* 始终显示消息。 */ (*cinfo->err->output_message) (cinfo); /* 将控制返回到 setjmp 点 */ longjmp(myerr->setjmp_buffer, 1);
【问题讨论】:
另外,我可以避免使用 setjmp() 和 longjmp()。如果您真的非常需要它们,它们很好,否则会很痛苦。 感谢您的建议。我将尝试在没有它的情况下使用 lib。我必须承认我使用的是来自 IJG 的 libjpeg 的示例,其中 setjmp() 的使用没有明确的解释...... 你不能在 IJG 中避免它们,因为它的错误报告函数并不意味着返回 :printf("ERROR\n"); abort(1);
,并且调用者不期望从它返回。因此,从它正常返回将完全完成程序流程的其余部分。
有趣的图书馆,IJG。图书馆非常罕见的模式。他们为什么这样做?
也许这是一个愚蠢的问题,但是:是否可以使用 IJG 的 lib 而不进行这种繁重的错误处理?
【参考方案1】:
205 是 0xCD,这是 VS 在调试模式下放在未初始化内存中的标准值,所以我认为您的 cinfo
在您调用解码器时没有正确初始化。使用时贴出代码。
另外,你使用的setjump()
让我觉得它是 IJG 库。小心它,因为它不是标准功能。当您进行调用时,它会记住线程和堆栈的确切状态,并且能够从任何地方返回到该位置,除非该状态不再有效,例如:
int init_fn()
if (setjump(my_state))
// ERROR!
;
return 0;
;
int decode()
init_fn();
do_work();
;
此处保存的状态在您调用实际解码器时无效。对于 MT 案例,您必须从与 longjmp()
相同的线程调用 setjump()
。
【讨论】:
是的,它是 IJG 库。当我有任何消息时,我会更深入地研究这些事情并发布,非常感谢! 刚刚编辑了原帖。我不认为我试图从不同的函数/线程调用 setjmp() 和 longjmp() 。 (不是 C 或 CRT 专家,这个问题很令人困惑......) 感谢有关 cinfo 的提示 - 即使问题稍后仍然存在,它也是实际答案。【参考方案2】:找到了我的问题的答案,部分归功于 ruslik。事实证明,我确实在两个函数之间初始化了 cinfo 和 jerr 。
但是当我更正这一点时,我仍然有“状态205”错误,并认为它在同一个地方。在我的日志中挖掘,我发现错误消息是在代码执行后期发出的,并且是由函数指针问题引起的。我自己的丑陋错误......
还是非常感谢!
【讨论】:
这些是jpeg_source_mgr
结构中的函数指针,是吗?我刚刚遇到了同样的Improper call to JPEG library in state 205
错误,因为我未能正确填充这些指针。以上是关于Libjpeg 错误 - 状态 205 中的不正确调用的主要内容,如果未能解决你的问题,请参考以下文章
./node_modules/graphql/index.mjs 中的错误 49:0-53:205 无法重新导出命名导出
PHP imagecreatefromstring(): gd-jpeg, libjpeg: 可恢复的错误