使用ijg支持JPEG - 获取访问冲突

Ken*_*art 3 c c++ jpeg ijg

我最近试图更新我的游戏以压缩格式(JPEG和PNG)存储图形.

虽然我最终选择了不同的库,但我最初的尝试是将ijg与JPEG解压缩结合起来.但是,我甚至无法使最简单的控制台应用程序工作,我想知道是否有人可能能够阐明原因.

这是我的代码,它链接到作为ijg包的一部分的jpeg.lib:

#include "stdafx.h"
#include <stdio.h>
#include <assert.h>
#include <jpeglib.h>

int _tmain(int argc, _TCHAR* argv[])
{
    struct jpeg_decompress_struct cinfo;
    struct jpeg_error_mgr jerr;
    JSAMPARRAY buffer;
    int row_stride;

    //initialize error handling
    cinfo.err = jpeg_std_error(&jerr);

    //initialize the decompression
    jpeg_create_decompress(&cinfo);

    FILE* infile;
    errno_t err = fopen_s(&infile, "..\\Sample.jpg", "rb");
    assert(err == 0);

    //specify the input
    jpeg_stdio_src(&cinfo, infile);

    //read headers
    (void) jpeg_read_header(&cinfo, TRUE);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

问题是调用jpeg_read_header()失败并出现访问冲突:

JPEGTest.exe中0x7c91b1fa(ntdll.dll)的未处理异常:0xC0000005:访问冲突写入位置0x00000010.

有没有人有任何想法我可能做错了什么?

Tal*_*man 7

我刚遇到同样的问题(虽然我试图对图像进行编码).显然,FILE*在DLL之间不可移植,因此您不能使用任何将FILE*作为参数的libjpeg API.

有几种解决方案,但它们都归结为必须重建库:

  • 将库构建为静态库,并将其链接到您的应用程序.这就是我所做的,它解决了我的问题.
  • 将源/目标处理程序移出libjpeg并进入应用程序.然后,您可以将libjpeg构建为静态库或DLL,以适合您的方式.我不确定这是否可行,但它是与源代码一起分发的"install.doc"文件中的建议解决方案.


Mat*_*hen 5

我同意 Hern\xc3\xa1n 的观点。这不是一个好的接口(我认为内部代码本身可能很好),除非您确实需要在低级别工作(甚至可能不需要)。我认为 ImageMagick 可能更好。他们有一个更高级别的“MagickWand”C 接口,更不用说它支持更多格式。

\n\n

但是,我对 libjpeg\ 的界面感到好奇,因此我根据您的示例程序以及libjpeg.docIJG 示例USING THE IJG JPEG LIBRARY ,得到了一个令我满意的测试程序。无论如何,这是代码。它只是打印出每行第一个像素的尺寸和 RGB。

\n\n

我很惊讶你的代码出现错误。它对我来说工作得很好,并且编译时没有任何警告。其他人可以测试一下吗?

\n\n
#include <stdio.h>\n#include <assert.h>\n#include <jpeglib.h>\n\nint main(int argc, char* argv[])\n{\n    struct jpeg_decompress_struct cinfo;\n    struct jpeg_error_mgr jerr;\n    JSAMPARRAY buffer;\n    int row_stride;\n\n    //initialize error handling\n    cinfo.err = jpeg_std_error(&jerr);\n\n    FILE* infile;\n    infile = fopen("Sample.jpg", "rb");\n    assert(infile != NULL);\n\n    //initialize the decompression\n    jpeg_create_decompress(&cinfo);\n\n    //specify the input\n    jpeg_stdio_src(&cinfo, infile);\n\n    //read headers\n    (void) jpeg_read_header(&cinfo, TRUE);\n\n    jpeg_start_decompress(&cinfo);\n\n    printf("width: %d, height: %d\\n", cinfo.output_width, cinfo.output_height);\n\n    row_stride = cinfo.output_width * cinfo.output_components;\n\n    buffer = (*cinfo.mem->alloc_sarray)\n        ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);\n\n    JSAMPLE firstRed, firstGreen, firstBlue; // first pixel of each row, recycled\n    while (cinfo.output_scanline < cinfo.output_height)\n    {\n    (void)jpeg_read_scanlines(&cinfo, buffer, 1);\n    firstRed = buffer[0][0];\n    firstBlue = buffer[0][1];\n    firstGreen = buffer[0][2];\n    printf("R: %d, G: %d, B: %d\\n", firstRed, firstBlue, firstGreen);\n    }\n\n    jpeg_finish_decompress(&cinfo);\n\n    return 0;\n}\n
Run Code Online (Sandbox Code Playgroud)\n