如何释放 libjpeg 创建的缓冲区?
How to release buffer created by libjpeg?
我正在使用 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 的指针。有什么想法吗?
我认为您的问题可能与您的 __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 导致了问题。我尝试将 libjpeg 重新编译为静态库,现在一切正常。
在我的例子中,没有办法释放内存图像指针,唯一的方法是为图像保留足够的内存,这样库就不会为我保留内存,我可以控制内存,内存将是我自己的应用程序的一部分,而不是库的 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
中保留
这样你就可以完全控制保留的内存,你可以在你的软件中随时释放它..
我正在使用 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 的指针。有什么想法吗?
我认为您的问题可能与您的 __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 导致了问题。我尝试将 libjpeg 重新编译为静态库,现在一切正常。
在我的例子中,没有办法释放内存图像指针,唯一的方法是为图像保留足够的内存,这样库就不会为我保留内存,我可以控制内存,内存将是我自己的应用程序的一部分,而不是库的 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
这样你就可以完全控制保留的内存,你可以在你的软件中随时释放它..