如何释放由Libjpeg创建的缓冲区?

3

我正在使用libjpeg将OpenCV Mat的图像缓冲区转换并写入内存位置。

以下是代码:

bool mat2jpeg(cv::Mat frame, unsigned char **outbuffer
    , long unsigned int *outlen) {

    unsigned char *outdata = frame.data;

    struct jpeg_compress_struct cinfo = { 0 };
    struct jpeg_error_mgr jerr;
    JSAMPROW row_ptr[1];
    int row_stride;

    *outbuffer = NULL;
    *outlen = 0;

    cinfo.err = jpeg_std_error(&jerr);
    jpeg_create_compress(&cinfo);
    jpeg_mem_dest(&cinfo, outbuffer, outlen);
    jpeg_set_quality(&cinfo, JPEG_QUALITY, TRUE);
    cinfo.image_width = frame.cols;
    cinfo.image_height = frame.rows;
    cinfo.input_components = 1;
    cinfo.in_color_space = JCS_GRAYSCALE;

    jpeg_set_defaults(&cinfo);
    jpeg_start_compress(&cinfo, TRUE);
    row_stride = frame.cols;

    while (cinfo.next_scanline < cinfo.image_height) {
        row_ptr[0] = &outdata[cinfo.next_scanline * row_stride];
        jpeg_write_scanlines(&cinfo, row_ptr, 1);
    }

    jpeg_finish_compress(&cinfo);
    jpeg_destroy_compress(&cinfo);


    return true;

}

事实上,我无法在任何地方进行outbuffer的解除分配。
这是我使用该函数的方式:
long unsigned int * __size__ = nullptr;

unsigned char * _buf = nullptr;

mat2jpeg(_img, &_buf, __size__);

无论是free(_buf)还是free(*_buf),都会失败。看起来我试图通过这样做释放堆的头部。

而mat2jpeg不接受指向指针的outbuffer。有什么想法吗?

3个回答

0

我已经验证了是dll引起的问题。我尝试将libjpeg重新编译为静态库,现在一切都像魔法般正常工作。


1
这里的问题实际上是libjpeg的问题--它似乎期望你在应该暴露一个函数让你调用来释放内存时自己释放内存,从而解决了可能由一个堆分配并在另一个堆上释放的问题。 - taxilian

0

我认为你的问题可能与你的__size__变量有关。它没有被分配到任何地方。根据我对libjpeg源代码的阅读,这意味着缓冲区从未被分配,程序调用了一个致命错误函数。

我认为你需要像这样调用它:

long unsigned int __size__ = 0; // not a pointer

unsigned char * _buf = nullptr;

mat2jpeg(_img, &_buf, &__size__); // send address of __size__

然后你应该能够使用以下代码释放缓冲区:

free(_buf);

这个答案是正确的,另外请注意只有在调用函数jpeg_finish_compress之后才能调用free(_buf),否则会导致段错误。 - Étienne
我无法通过使用.dll或.lib来解决这个问题。每当我尝试调用free(_buf)时,都会出现错误。 - KronuZ
@KronuZ 这个回答正确地修复了这个问题中提供的代码的问题(发送未分配整数的地址)。如果它不能解决你的代码问题,为什么不发布一个你自己的带有具体代码和具体问题的问题呢? - Galik
我的代码几乎和问题中的一样,但这个解决方案对我不起作用。 - KronuZ
@KronuZ 但是这个答案确实修复了此问题中代码中的一个错误。因此,这是对所发布问题的一个很好且重要的回答。 - Galik
显示剩余2条评论

0
在我的情况下,没有办法释放内存图像指针,唯一的方法是为图像保留足够的内存,这样库就不会为我保留内存,我可以控制内存,内存将成为我的应用程序的一部分,而不是库的dll或.lib。
//previous code...
struct jpeg_compress_struct cinfo;

//reserving the enough memory for my image (width * height)
unsigned char* _image = (unsigned char*)malloc(Width * Height);

//putting the reserved size into _imageSize
_imageSize = Width * Height;

//call the function like this:
jpeg_mem_dest(&cinfo, &_image, &_imageSize);
................
//releasing the reserved memory
free(_image);

注意:如果您将_imageSize = 0,库将假定您没有保留内存,并且自己的库将执行此操作。因此,您需要在_imageSize中放置在_image中保留的字节数。

这样,您就可以完全控制保留的内存,并可以随时在软件中释放它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接