我最近尝试更新my game以压缩格式(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;
}
问题是对jpeg_read_header()
的调用因访问冲突而失败:
0x7c91b1fa处的未处理异常 JPEGTest.exe中的(ntdll.dll): 0xC0000005:访问冲突写入 位置0x00000010。
有没有人有任何想法我可能做错了什么?
答案 0 :(得分:7)
我刚遇到同样的问题(虽然我试图对图像进行编码)。 显然,FILE *在DLL之间不可移植,因此您不能使用任何将FILE *作为参数的libjpeg API。
有几种解决方案,但它们都归结为必须重建库:
答案 1 :(得分:4)
我同意Hernán。这不是一个好的界面(我认为内部代码本身可能很好),除非你真的需要低级工作(甚至可能不是那么)。我认为ImageMagick可能更好。他们有一个更高级别的“MagickWand”C界面,更不用说它支持更多格式了。
然而,我对libjpeg的界面感到好奇,所以根据你的示例程序以及libjpeg.doc,IJG example和USING THE IJG JPEG LIBRARY,我得到了一个令我满意的测试程序。 。无论如何,这是代码。它只打印尺寸和每行第一个像素的RGB。
我很惊讶你的代码出错了。它适用于我,并编译没有任何警告。别人可以测试一下吗?
#include <stdio.h>
#include <assert.h>
#include <jpeglib.h>
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;
}
答案 2 :(得分:2)
这是一个解决方法,无需重建库:更换I / O函数,正如AndréCaron所说,但除了标准的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”。你看它基本上是一个兼容性问题。
我希望这样或类似的东西能解决问题。
答案 3 :(得分:1)
很难从给定的代码示例中看到访问冲突的原因。如果您可以包含有助于识别问题的堆栈跟踪(带符号)。 要验证的一件事是.LIB和.EXE项目的对齐设置是一致的,这通常会导致令人讨厌的问题,因为struct / class成员不是编译器期望它们的位置。
答案 4 :(得分:0)
要处理多种格式的图片,我建议您将DevIL作为库http://openil.sourceforge.net/。这是一个很好的选择,因为我已经多次使用它并且效果很好。请注意它的语法是类似OpenGL的。
功能列表:
支持加载:
支持保存:
图书馆功能
答案 5 :(得分:0)
这是一个经过测试的功能
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);
}
答案 6 :(得分:0)
这个问题现在差不多已经有10年了,但是今天作者发给我的东西却完全一样(我使用的是Visual Studio 2013)。
最初,我尝试使用GnuWin32中的libjpeg库:http://gnuwin32.sourceforge.net/packages/jpeg.htm,并遇到相同的错误。 然后注意到这是libJpeg的“版本6b” ,现在已经很旧了(2005年) 对我有用的是通过nuget pacakge管理器安装libJpeg:
安装软件包libjpeg-版本9.2.0.1