1

我在 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 次迭代后崩溃,我最好的猜测是我将数据从向量转换为指针数组很糟糕。

无论如何,我无法弄清楚如何更好地分配内存,或者这甚至是问题所在

任何关于我做错了什么的想法以及关于如何在未来实际调试它的任何提示都将不胜感激。

编辑

我更改trueTRUE并打印出数组中的每个字节,如下所示

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 的图像数据损坏的想法

4

2 回答 2

1

我在您的代码中没有发现任何问题,除了在这些调用true中传递了 C++ bool 值而不是 C 值:TRUE

    jpeg_set_quality(&cinfo, 100, true);
    ...
    jpeg_start_compress(&cinfo, true);

有时可能会导致奇怪的崩溃。

此外,在这种情况下我会尝试的第一件事——如果只是在某处输出每一行的所有字节arr[cinfo.next_scanline * row_stride]——它会崩溃吗?如果是这样,则可能您在准备图像数据的其他代码中有错误。

UPD .:原始代码的问题很可能是#include <jpeglib.h>- 这应该强制在系统目录而不是 libjpeg-turbo 目录中搜索 jpeglib.h。这可以通过使用 #include "jpeglib.h"并指定编译器的 libjpeg-turbo 包含目录的路径来解决。

于 2021-08-30T21:08:16.560 回答
0

感谢所有的帮助,正如@AntonMalyshev 指出的那样,问题是libjpeg 的使用不正确。

首先我已经libjpeg-turbo安装了,虽然它包含一个库,但libjpeg我确信更好的做法是libjpeg直接安装。我最终使用了#include <turbojpeg.h>.

其次,我发布的示例代码似乎只与 base 兼容libjpeg使用这篇文章libjpeg-turbo api我能够想出一个可行的解决方案。

谢谢,伊桑

于 2021-09-01T09:35:31.303 回答