簡體   English   中英

如何使用jpeg_mem_dest使用libjpeg-turbo壓縮到內存

[英]How to compress to memory with libjpeg-turbo using jpeg_mem_dest

我嘗試過另一個答案,但似乎無法做到這一點。 我有大約8MiB的RBGX位圖使用libjpeg-turbo轉換為內存中的jpeg。 如果我使用jpeg_stdio_dest我可以將整個文件寫入文件,然后重新讀取文件,就可以了。 但是,嘗試使用jpeg_mem_dest一直是個難題。 我有與jpeg_stdio_dest相同的設置,但是使用mem似乎只進行一次4KiB分配,然后再也不再分配任何空間。

我找不到有關如何使用jpeg_mem_dest進一步說明的文檔,並且可以真正使用某個方向。

void compress(std::vector<unsigned char>& input) {
  jpeg_compress_struct cinfo{};
  jpeg_error_mgr err{};

  cinfo.err = jpeg_std_error(&err);
  jpeg_create_compress(&cinfo);
#if 0 // using this with an open FILE* out works
  jpeg_stdio_dest(&cinfo, out);
#endif


  cinfo.image_width = kWidth; // constants defined somewhere
  cinfo.image_height = kHeight;
  cinfo.input_components = 4;
  cinfo.in_color_space = JCS_EXT_RGBX;

  // what's wrong with this?
  unsigned char* buf{};
  unsigned long buf_sz{};
  jpeg_mem_dest(&cinfo, &buf, &buf_sz);

  jpeg_set_defaults(&cinfo);
  jpeg_set_quality(&cinfo, 70, true);

  jpeg_start_compress(&cinfo, true);   
  while (cinfo.next_scanline < cinfo.image_height) {
    auto row = static_cast<JSAMPROW>(&input[cinfo.next_scanline  * 4  * kWidth]);
    jpeg_write_scanlines(&cinfo, &row, 1);
    // Always prints 4096, and buf never changes 
    std::cout << "buf_sz: " << buf_sz 
              << " buf: " << static_cast<void*>(buf) << '\n';
  }
  jpeg_finish_compress(&cinfo);

  // ...
  // in reality, return the compressed data
}

是的,這根本不直觀。 提出jpeg_mem_dest()調整的程序員沒有太多選擇,擴展現有的api並不是那么容易,因為它不是為了首先支持一個功能而設計的。 什么是完全不明顯的是你的變量直到jpeg_finish_compress()調用之后才會更新。 庫中的相關代碼是:

METHODDEF(void)
term_mem_destination (j_compress_ptr cinfo)
{
  my_mem_dest_ptr dest = (my_mem_dest_ptr) cinfo->dest;

  *dest->outbuffer = dest->buffer;
  *dest->outsize = (unsigned long)(dest->bufsize - dest->pub.free_in_buffer);
}

請注意“術語”一詞。 通過函數指針間接調用此函數:

GLOBAL(void)
jpeg_finish_compress (j_compress_ptr cinfo)
{
  //...
  /* Write EOI, do final cleanup */
  (*cinfo->marker->write_file_trailer) (cinfo);
  (*cinfo->dest->term_destination) (cinfo);
  //...
}

你無能為力。 只需調整你的std :: cout代碼,在循環之后移動它以適應庫的工作方式。

要注意這個功能的其他細節,也不是很明顯。 你必須釋放()它創建的緩沖區。 在提供的cjpeg.c示例程序中可見,main()結束。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM