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

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

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

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

#include "stdafx.h" #include  #include  #include  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; } 

问题是对jpeg_read_header()的调用因访问冲突而失败:

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

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

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

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

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

我同意Hernán。 这不是一个好的界面(我认为内部代码本身可能很好),除非你真的需要低级工作(甚至可能不是那么)。 我认为ImageMagick可能更好。 他们有一个更高级别的“MagickWand”C界面,更不用说它支持更多格式了。

但是,我对libjpeg的界面感到好奇,所以基于你的示例程序以及libjpeg.doc , IJG示例和使用IJG JPEG LIBRARY ,我得到了一个令我满意的测试程序。 无论如何,这是代码。 它只打印出尺寸,以及每行第一个像素的RGB。

我很惊讶你的代码出错了。 它适用于我,并编译没有任何警告。 别人可以测试一下吗?

 #include  #include  #include  int main(int argc, char* 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); FILE* infile; infile = fopen("Sample.jpg", "rb"); assert(infile != NULL); //initialize the decompression jpeg_create_decompress(&cinfo); //specify the input jpeg_stdio_src(&cinfo, infile); //read headers (void) jpeg_read_header(&cinfo, TRUE); jpeg_start_decompress(&cinfo); printf("width: %d, height: %d\n", cinfo.output_width, cinfo.output_height); row_stride = cinfo.output_width * cinfo.output_components; buffer = (*cinfo.mem->alloc_sarray) ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1); JSAMPLE firstRed, firstGreen, firstBlue; // first pixel of each row, recycled while (cinfo.output_scanline < cinfo.output_height) { (void)jpeg_read_scanlines(&cinfo, buffer, 1); firstRed = buffer[0][0]; firstBlue = buffer[0][1]; firstGreen = buffer[0][2]; printf("R: %d, G: %d, B: %d\n", firstRed, firstBlue, firstGreen); } jpeg_finish_decompress(&cinfo); return 0; } 

这是一个解决方法,无需重建库:如AndréCaron所说,制作替换I / O函数,但除了标准的stdio函数之外什么也没有。

我在过去做的代码可能有所帮助。 它是为libpng编写的,但我相信在libjpeg中也很容易做到这一点。

我在代码中添加了这个:

  png_set_write_fn (png_ptr,file,replwrite,replflush); 

然后创建了替换函数:

 void replwrite (png_structp png_ptr, png_bytep data, png_size_t length) { fwrite (data,1,length,(FILE*) png_get_io_ptr(png_ptr)); } void replflush (png_structp png_ptr) { fflush ((FILE*) png_get_io_ptr(png_ptr)); } 

它总是适合我。 我实际上在做的是告诉libpng,“嘿,不要使用你的.dll指向的MSVCR中的写函数,使用这些函数来自我在我的程序中使用的MSVCR,fwrite和fflush”。 你看它基本上是一个兼容性问题。

我希望这样或类似的东西能解决问题。

从给定的代码示例中很难看出访问冲突的原因。 如果您可以包含有助于识别问题的堆栈跟踪(带符号)。 要validation的一件事是.LIB和.EXE项目的对齐设置是一致的,这通常会导致令人讨厌的问题,因为struct / class成员不是编译器期望它们的位置。

要使用多种格式的图像,我建议您将DevIL作为库http://sofzh.miximages.com/c%2B%2B/404.php

  • 。切
  • .DCX
  • 的.dds
  • .exr
  • .ICO
  • .icns
  • .gif注意
  • .JPG
  • .jp2
  • .lbm
  • .lif
  • .mdl文件
  • .PCD
  • .PCX
  • .PIC
  • 巴纽
  • .pnm
  • .PSD
  • .psp
  • 。生的
  • .sgi
  • .TGA
  • .TIF
  • .wal
  • 。法案
  • 。朋友
  • .HDR
  • 毁灭图形
  • 支持节省:

    • .BMP
    • 的.dds
    • .JPG
    • .PCX
    • 巴纽
    • .pnm
    • 。生的
    • .sgi
    • .TGA
    • .TIF
    • 。朋友

    图书馆特色

    • 便携式,支持Windows,Mac OS X和* nix。
    • OpenGL风格的语法。
    • 使用图像名称而不是丑陋的指针。
    • 从文件,文件流或内存“块”加载。
    • 通过ilGetData()和ilSetData()直接访问数据。
    • 支持亮度,rgb(a),bgr(a)和颜色索引图像。
    • 每个通道支持3个不同的位数。
    • 所有格式和数据类型(包括调色板)之间的转换。
    • 加载图像时,如果需要,用户定义的自动转换。
    • 根据需要保存图像时自动转换。
    • 如果需要,可以将颜色索引图像自动转换为真彩色图像。
    • 保存时可控压缩。
    • 维护可以推送和弹出的状态堆栈。
    • 完全支持3d纹理体积(3d图像)。
    • validation图像。
    • 支持图层。
    • 支持mipmap。
    • 支持动画。
    • 用户指定的清晰颜色。
    • 如果加载失败,可以加载默认图像。
    • 用户指定的提示。
    • 使用关键颜色。
    • 支持将图像叠加在另一个上面。
    • 允许用户指定自己的加载和保存回调,甚至覆盖默认回调。
    • 支持用户指定的读写function。
    • Delphi支持。
    • Visual Basic支持。
    • Linux支持。
    • 可以选择将用于创建较小dll的function。
    • 选择是使用Intel Jpeg Library还是libjpeg。
    • 应用于图像的大量效果和滤镜,例如压花和边缘检测。
    • 图像可以resize,甚至可以放在更大的背景(放大的canvas)上。
    • OpenGL,Allegro,Windows GDI和DirectX API支持。

    这是一个经过测试的function

     void test(char FileName[]) { unsigned long x, y; struct jpeg_decompress_struct info; //for our jpeg info struct jpeg_error_mgr err; //the error handler JSAMPARRAY buffer; FILE* infile; //initialize error handling info.err = jpeg_std_error(& err); infile = fopen(FileName, "rb"); //open the file //if the jpeg file doesn't load if(!infile) { fprintf(stderr, "Error reading JPEG file %s!", FileName); // printf("Error reading JPEG file %s!", FileName); //return 0; } //initialize the decompression jpeg_create_decompress(&info); //specify the input jpeg_stdio_src(&info, infile); //read headers jpeg_read_header(&info, TRUE); // read jpeg file header jpeg_start_decompress(&info); // decompress the file //set width and height x = info.output_width; y = info.output_height; printf("x value is %ul", x); printf("x value is %ul", y); }