LZO 压缩字符*

发布于 2024-10-02 20:59:57 字数 2176 浏览 3 评论 0原文

我已经在我的 Ubuntu 机器上安装了 LZO,我想使用 ti 来压缩 char* 类型的字符串。

在示例文件中,我找到了这个代码片段(我已经为我的应用程序对其进行了一些编辑):

  int r;
  lzo_bytep in;
  lzo_bytep out;
  lzo_voidp wrkmem;
  lzo_uint in_len;
  lzo_uint out_len;
  lzo_uint new_len;
  int strToCompressLen; // I have added this

  /*
   * Step 1: initialize the LZO library
   */
  if (lzo_init() != LZO_E_OK)
  {
    cout << "internal error - lzo_init() failed !!!" << endl;
    cout << "(this usually indicates a compiler bug - try recompiling\nwithout optimizations, and enable '-DLZO_DEBUG' for diagnostics)" << endl;
    //return 4;
  }

  // here I get the data I want to compress
  char* imageData = (char*)imageIn->getFrame();

  /*
   * Step 2: allocate blocks and the work-memory
   */
  strToCompressLen = strlen(imageData);
  in = (lzo_bytep) xmalloc(strToCompressLen);
  out = (lzo_bytep) xmalloc((strToCompressLen + strToCompressLen / 16 + 64 + 3));
  wrkmem = (lzo_voidp) xmalloc(LZO1X_1_MEM_COMPRESS);
  if (in == NULL || out == NULL || wrkmem == NULL)
  {
        cout << "out of memory" << endl;
        //return 3;
  }

  /*
   * Step 3: prepare the input block that will get compressed.
   *         We just fill it with zeros in this example program,
   *         but you would use your real-world data here.
   */
  in_len = strToCompressLen;
  lzo_memset(in,0,in_len);

  /*
   * Step 4: compress from 'in' to 'out' with LZO1X-1
   */
  r = lzo1x_1_compress(in,in_len,out,&out_len,wrkmem);
  if (r != LZO_E_OK)
  {
        /* this should NEVER happen */
        cout << "internal error - compression failed: " << r << endl;
        //return 2;
  }
  /* check for an incompressible block */
  if (out_len >= in_len)
  {
        cout << "This block contains incompressible data." << endl;
    //return 0;
  }

但它所做的只是填充零。我需要压缩 char* 变量。

我想我需要编辑这些行:

  in_len = strToCompressLen;
  lzo_memset(in,0,in_len);

我有要在此变量中压缩的字符串:

  char* imageData = (char*)imageIn->getFrame();

我需要将其转换为其他类型吗?

LZO 的文档不是很有帮助(或者也许我只是无法正确使用它)。

I have installed LZO on my Ubuntu machine and I would like to use ti to compress a char* type string.

In the example files I have found this code snippet (I have already edited it just a little for my application):

  int r;
  lzo_bytep in;
  lzo_bytep out;
  lzo_voidp wrkmem;
  lzo_uint in_len;
  lzo_uint out_len;
  lzo_uint new_len;
  int strToCompressLen; // I have added this

  /*
   * Step 1: initialize the LZO library
   */
  if (lzo_init() != LZO_E_OK)
  {
    cout << "internal error - lzo_init() failed !!!" << endl;
    cout << "(this usually indicates a compiler bug - try recompiling\nwithout optimizations, and enable '-DLZO_DEBUG' for diagnostics)" << endl;
    //return 4;
  }

  // here I get the data I want to compress
  char* imageData = (char*)imageIn->getFrame();

  /*
   * Step 2: allocate blocks and the work-memory
   */
  strToCompressLen = strlen(imageData);
  in = (lzo_bytep) xmalloc(strToCompressLen);
  out = (lzo_bytep) xmalloc((strToCompressLen + strToCompressLen / 16 + 64 + 3));
  wrkmem = (lzo_voidp) xmalloc(LZO1X_1_MEM_COMPRESS);
  if (in == NULL || out == NULL || wrkmem == NULL)
  {
        cout << "out of memory" << endl;
        //return 3;
  }

  /*
   * Step 3: prepare the input block that will get compressed.
   *         We just fill it with zeros in this example program,
   *         but you would use your real-world data here.
   */
  in_len = strToCompressLen;
  lzo_memset(in,0,in_len);

  /*
   * Step 4: compress from 'in' to 'out' with LZO1X-1
   */
  r = lzo1x_1_compress(in,in_len,out,&out_len,wrkmem);
  if (r != LZO_E_OK)
  {
        /* this should NEVER happen */
        cout << "internal error - compression failed: " << r << endl;
        //return 2;
  }
  /* check for an incompressible block */
  if (out_len >= in_len)
  {
        cout << "This block contains incompressible data." << endl;
    //return 0;
  }

But what it does is it just fill in zeros. I need to compress a char* variable.

I guess I need to edit these lines:

  in_len = strToCompressLen;
  lzo_memset(in,0,in_len);

I have the string I want to compress in this variable:

  char* imageData = (char*)imageIn->getFrame();

Do I need to cast it to some other type?

The documentation to LZO is not very helpful (or maybe I just can't use it properly).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

酒中人 2024-10-09 20:59:57

主要有以下三个容易混淆的地方:

  1. 最好不要使用 char*
    指针指向的缓冲区是
    不是一个以空字符结尾的字符串
    令人困惑。
  2. strlen() 只会给你
    以 null 结尾的字符串的长度,
    它不会给你一个大小
    内存中的任意缓冲区。你需要
    从其他地方获取该信息。
  3. 您传递到的缓冲区
    lzo1x_1_compress() 实际上需要
    包含你想要的数据
    压缩而不是空缓冲区
    充满了零。

假设您可以使用 imageIn->getFrameSizeBytes() 之类的方法从 imageIn 获取图像的大小,请尝试以下操作:

  int r;
  lzo_bytep out;
  lzo_voidp wrkmem;
  lzo_uint out_len;
  lzo_uint new_len;

  /*
   * Step 1: initialize the LZO library
   */
  if (lzo_init() != LZO_E_OK)
  {
    cout << "internal error - lzo_init() failed !!!" << endl;
    cout << "(this usually indicates a compiler bug - try recompiling\nwithout optimizations, and enable '-DLZO_DEBUG' for diagnostics)" << endl;
    //return 4;
  }

  // here I get the data I want to compress
  lzo_bytep imageData = (lzo_bytep) imageIn->getFrame();
  size_t uncompressedImageSize = imageIn->getFrameSizeBytes();

  /*
   * Step 2: allocate blocks and the work-memory
   */
  out = (lzo_bytep) xmalloc((uncompressedImageSize + uncompressedImageSize / 16 + 64 + 3));
  wrkmem = (lzo_voidp) xmalloc(LZO1X_1_MEM_COMPRESS);
  if (out == NULL || wrkmem == NULL)
  {
        cout << "out of memory" << endl;
        //return 3;
  }

  /*
   * Step 4: compress from 'imageData' to 'out' with LZO1X-1
   */
  r = lzo1x_1_compress(imageData,uncompressedImageSize,out,&out_len,wrkmem);
  if (r != LZO_E_OK)
  {
        /* this should NEVER happen */
        cout << "internal error - compression failed: " << r << endl;
        //return 2;
  }

  /* check for an incompressible block */
  if (out_len >= uncompressedImageSize)
  {
        cout << "This block contains incompressible data." << endl;
    //return 0;
  }

不要忘记释放 wrkmem。更好的是,使用 C++ 和 std::vector 作为工作内存,以便自动释放它。

There are three main points of confusion:

  1. It's best not to use char* when the
    buffer the pointer is pointing to is
    not a null-terminated string as it's
    confusing.
  2. strlen() will only give you the
    length of a null-terminated string,
    it won't give you the size of an
    arbitrary buffer in memory. You need
    to get that information elsewhere.
  3. The buffer you pass to
    lzo1x_1_compress() actually needs to
    contain the data you want to
    compress and not an empty buffer
    full of zeros.

Assuming you can get the size of your image from imageIn using something like imageIn->getFrameSizeBytes(), try this:

  int r;
  lzo_bytep out;
  lzo_voidp wrkmem;
  lzo_uint out_len;
  lzo_uint new_len;

  /*
   * Step 1: initialize the LZO library
   */
  if (lzo_init() != LZO_E_OK)
  {
    cout << "internal error - lzo_init() failed !!!" << endl;
    cout << "(this usually indicates a compiler bug - try recompiling\nwithout optimizations, and enable '-DLZO_DEBUG' for diagnostics)" << endl;
    //return 4;
  }

  // here I get the data I want to compress
  lzo_bytep imageData = (lzo_bytep) imageIn->getFrame();
  size_t uncompressedImageSize = imageIn->getFrameSizeBytes();

  /*
   * Step 2: allocate blocks and the work-memory
   */
  out = (lzo_bytep) xmalloc((uncompressedImageSize + uncompressedImageSize / 16 + 64 + 3));
  wrkmem = (lzo_voidp) xmalloc(LZO1X_1_MEM_COMPRESS);
  if (out == NULL || wrkmem == NULL)
  {
        cout << "out of memory" << endl;
        //return 3;
  }

  /*
   * Step 4: compress from 'imageData' to 'out' with LZO1X-1
   */
  r = lzo1x_1_compress(imageData,uncompressedImageSize,out,&out_len,wrkmem);
  if (r != LZO_E_OK)
  {
        /* this should NEVER happen */
        cout << "internal error - compression failed: " << r << endl;
        //return 2;
  }

  /* check for an incompressible block */
  if (out_len >= uncompressedImageSize)
  {
        cout << "This block contains incompressible data." << endl;
    //return 0;
  }

Don't forget to free wrkmem. Even better, use C++ and std::vector for the working memory so it is freed automatically.

深空失忆 2024-10-09 20:59:57

getFrame() 返回什么类型?为什么需要将其转换为 char*?最明显的问题是对二进制数据使用 strlen() —— strlen 在遇到第一个零字节时停止。

What type does getFrame() return? Why do you need to cast it to char*? The most obvious problem is using strlen() on binary data -- strlen stops when it encounters the first zero-byte.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文