我在 QT Creator 的 Windows 10 上运行了以下代码,我正在尝试使用 libjpeg-turbo 库将 rgb 格式的数据写入 jpeg 文件
#include <stdio.h>
#include <jpeglib.h>
void writeJpeg(const char *filename, std::vector<unsigned char> &image, uint w, uint h) {
struct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;
FILE *outfile;
JSAMPROW row_pointer[1];
int row_stride;
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_compress(&cinfo);
if ((outfile = fopen(filename, "wb")) == NULL) {
fprintf(stderr, "can't open %s\n", filename);
exit(1);
}
jpeg_stdio_dest(&cinfo, outfile);
cinfo.image_width = w;
cinfo.image_height = h;
cinfo.input_components = 3;
cinfo.in_color_space = JCS_RGB;
jpeg_set_defaults(&cinfo);
jpeg_set_quality(&cinfo, 100, true);
jpeg_start_compress(&cinfo, true);
row_stride = w * 3;
JSAMPLE *arr = image.data();
while (cinfo.next_scanline < cinfo.image_height) {
row_pointer[0] = &arr[cinfo.next_scanline * row_stride];
(void)jpeg_write_scanlines(&cinfo, row_pointer, 1);
}
jpeg_finish_compress(&cinfo);
fclose(outfile);
jpeg_destroy_compress(&cinfo);
}
继续SIGSEGV
这(void)jpeg_write_scanlines(&cinfo, row_pointer, 1);
部分代码
while (cinfo.next_scanline < cinfo.image_height) {
row_pointer[0] = &arr[cinfo.next_scanline * row_stride];
(void)jpeg_write_scanlines(&cinfo, row_pointer, 1);
}
我试过调试,但我不完全确定最好的方法是什么。
我发现它在循环 15 次迭代后崩溃,我最好的猜测是我将数据从向量转换为指针数组很糟糕。
无论如何,我无法弄清楚如何更好地分配内存,或者这甚至是问题所在
任何关于我做错了什么的想法以及关于如何在未来实际调试它的任何提示都将不胜感激。
编辑
我更改true
为TRUE
并打印出数组中的每个字节,如下所示
while (cinfo.next_scanline < cinfo.image_height) {
row_pointer[0] = &arr[cinfo.next_scanline * row_stride];
QString out = "";
for (int i = 0; i<row_stride; i++)
out += QString::number(row_pointer[0][i]) + " ";
qDebug() << "\n\n==============" << cinfo.next_scanline << "==============\n\n";
qDebug() << out;
(void)jpeg_write_scanlines(&cinfo, row_pointer, 1);
}
在逐步执行之后,它能够输出所有字节,但仍然崩溃write_jpeg_scanlines
我还注意到在每个扫描线的末尾打印出一些随机文本,例如:
255 255 255 25520003200!-�U3
在第 12 行
255 255 255 255eencoded�/�Rf
在第 13 行
231 230 230 255,autoder�)�Pu
在第 15 行,它崩溃的数据
不确定这是否只是指针末尾的垃圾,还是一种症状,qDebug
但它可以确认 antons 的图像数据损坏的想法