Как освободить буфер, созданный 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;

}

Дело в том, что я нигде не могу освободить outbuffer.

Вот как я использую функцию:

long unsigned int * __size__ = nullptr;

unsigned char * _buf = nullptr;

mat2jpeg(_img, &_buf, __size__);

как free(_buf), так и free(*_buf) терпит неудачу, кажется, что я пытаюсь таким образом освободить голову кучи.

и mat2jpeg не примет указатель на указатель для буфера. любая идея?

3 ответа

Решение

Я думаю, что ваша проблема может быть с вашим __size__ переменная. Его нигде не выделено. Согласно моему прочтению исходного кода libjpeg, это означает, что буфер никогда не выделяется и программа вызывает фатальную ошибку.

Я думаю, вам нужно назвать это так:

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

unsigned char * _buf = nullptr;

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

Тогда вы сможете освободить буфер с помощью:

free(_buf);

Я проверил, что это DLL, что вызвало проблему. Я попытался перекомпилировать libjpeg как статическую библиотеку, и теперь все работает как шарм.

В моем случае не было возможности освободить указатель изображения в памяти, единственный способ сделать это - зарезервировать достаточно памяти для изображения, и таким образом библиотека не будет резервировать память, и я контролирую память и находится в той же куче моего приложения, а не в куче библиотеки, вот мой пример:

      //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

Таким образом, у вас будет полный контроль над зарезервированной памятью и вы сможете освободить ее, когда захотите, в своем программном обеспечении.

Другие вопросы по тегам