【问题标题】:How to release buffer created by libjpeg?如何释放由 libjpeg 创建的缓冲区?
【发布时间】:2015-12-11 18:41:46
【问题描述】:

我正在使用 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;

}

问题是我无法在任何地方释放出缓冲区。

这是我使用函数的方式:

long unsigned int * __size__ = nullptr;

unsigned char * _buf = nullptr;

mat2jpeg(_img, &_buf, __size__);

free(_buf) 和 free(*_buf) 都失败了 看来我正试图通过这样做来释放堆头。

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

【问题讨论】:

    标签: c++ opencv memory-leaks libjpeg libjpeg-turbo


    【解决方案1】:

    我认为您的问题可能与您的 __size__ 变量有关。它没有分配到任何地方。根据我对libjpeg source code 的阅读,这意味着永远不会分配缓冲区,并且程序会调用致命错误函数。

    我认为你需要这样称呼它:

    long unsigned int __size__ = 0; // not a pointer
    
    unsigned char * _buf = nullptr;
    
    mat2jpeg(_img, &_buf, &__size__); // send address of __size__
    

    那么你应该可以通过以下方式释放缓冲区:

    free(_buf);
    

    【讨论】:

    • 我根据你的评论改了。并且错误仍然存​​在。
    • 我认为问题可能是由于释放了在第三方 dll 中分配的内存。所以我试图释放 jpeg.dll 分配的内存。但是 dll 有不同的堆管理器。我将进一步从源代码构建以验证这一点。
    • 这个答案是对的,另外请注意你只能在函数 jpeg_finish_compress 被调用之后才能调用 free(_buf),否则你会得到一个段错误。
    • 这样我无法解决问题,既不使用.dll也不使用.lib..每当我尝试调用free(_buf)时总是给我一个错误..
    • @KronuZ 此答案正确解决了此问题中提供的代码的问题(发送未分配整数的地址)。如果它不能修复您的代码,为什么不使用您的特定代码和特定问题发布您自己的问题?
    【解决方案2】:

    我已确认是导致问题的 dll。我尝试将 libjpeg 重新编译为静态库,现在一切都像魅力一样工作。

    【讨论】:

    • 这里的问题实际上是 libjpeg 的一个问题——它似乎希望您在它应该公开一个函数供您调用以释放内存时释放内存,从而解决了它可能由一个堆分配并在另一个堆上释放
    【解决方案3】:

    在我的情况下,没有办法释放内存图像指针,唯一的方法是为图像保留足够的内存,这样库就不会为我保留内存,我可以控制内存,内存将是我自己的应用程序的一部分,而不是库的 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中保留的字节数

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-12-14
      • 1970-01-01
      • 2015-03-25
      • 2016-07-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多