LZO компресс чар * - PullRequest
       11

LZO компресс чар *

1 голос
/ 19 ноября 2010

Я установил LZO на мою машину с Ubuntu и хотел бы использовать 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 не очень полезна (или, может быть, я просто не могу правильно ее использовать).

Ответы [ 2 ]

2 голосов
/ 19 ноября 2010

Есть три основных вопроса путаницы:

  1. Лучше не использовать char *, когда буфер, на который указывает указатель не завершенная нулем строка, поскольку это сбивает с толку.
  2. strlen () даст вам только длина строки с нулевым символом в конце, это не даст вам размер произвольный буфер в памяти. Тебе нужно чтобы получить эту информацию в другом месте.
  3. Буфер, который вы передаете lzo1x_1_compress () на самом деле нужно содержать данные, которые вы хотите сжимать а не пустой буфер полный нулей.

Предполагая, что вы можете получить размер изображения из imageIn, используя что-то вроде imageIn-> getFrameSizeBytes (), попробуйте это:

  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 для рабочей памяти, чтобы она автоматически освобождалась.

2 голосов
/ 19 ноября 2010

Какой тип возвращает getFrame ()? Зачем вам нужно привести его к char*? Наиболее очевидная проблема - использование strlen() для двоичных данных - strlen останавливается, когда встречает первый нулевой байт.

...