Я использую компрессор LZ4 C lib. Некоторые из файлов, которые я сжимаю, - это JPG и PNG. По какой-то причине, которую я не понимаю, метод

 int compressedSize =   LZ4_compress_default((char*)data,
            compressedData, uncompressedSize, uncompressedSize);

Иногда возвращает отрицательные значения для изображений (или ноль), которые я сжимаю.

Например, я сжимаю два стандартных изображения JPG. Один возвращает значение «-236», а второй возвращает точное количество сжатых байтов, что означает, что первый не смог сжать. Нулевой возврат означает, что LZ4 не сжимался. Понятия не имею, что означает -236. Это потому, что исходные данные в какой-то степени уже сжаты?

1
Michael IV 27 Дек 2016 в 17:05
4
Я предполагаю, что сжатая версия действительно стала больше, чем оригинал (что не редкость для JPEG, попробуйте заархивировать изображение jpeg и сами посмотрите результаты), и, следовательно, отрицательное число.
 – 
kuruczgyurci
27 Дек 2016 в 17:09
Вы проверили exampled @ github.com/lz4/lz4/blob/dev? /examples/compress_functions.c после строки 248. т.е. использование maxcompsize
 – 
HRgiger
27 Дек 2016 в 17:12
Я думал, что функция вернула количество байтов, полученных при сжатии (original_size - compressed_size), но похоже, что я ошибался. В руководстве lz4 говорится о возвращаемом значении: return: количество байтов, записанных в буфер 'dest' (обязательно <= maxOutputSize) или 0 в случае сбоя сжатия . Кажется, что здесь не упоминаются отрицательные значения.
 – 
kuruczgyurci
27 Дек 2016 в 17:19
1
Ты получил точку
 – 
Michael IV
27 Дек 2016 в 18:00
3
Затем используйте режим хранения, такой как zip, в вашей «zip-подобной программе», чтобы не тратить время на сжатие уже сжатых вещей.
 – 
Mark Adler
28 Дек 2016 в 02:30

1 ответ

Лучший ответ

Определение возврата функции:

  return : the number of bytes written into buffer 'dest' (necessarily <= maxOutputSize)
           or 0 if compression fails

Если сжатие привело к размеру больше, чем uncompressedSize, что весьма вероятно для уже сжатого файла, функция завершится ошибкой. Однако это не объясняет, почему он вернул отрицательное значение - это не задокументировано. Но остается в том случае, если вам нужно разместить сжатые файлы, вам нужно разрешить увеличение размера файла, предоставив больший буфер.

Глядя на исходный код, возвращаемое значение генерируется в LZ4_compress_generic() от:

return (int) (((char*)op)-dest);

Арифметика указателя вернет отрицательное значение, если op <dest, хотя, глядя на код, трудно понять, как это могло произойти. Если это вызывает беспокойство (и, конечно, если просто предоставление большего целевого буфера не решает проблему), я предлагаю вам выполнить код в отладчике, чтобы определить, в чем проблема.

4
Clifford 27 Дек 2016 в 17:38
1
Const size_t max_dst_size = LZ4_compressBound (src_size); решает проблему
 – 
Michael IV
27 Дек 2016 в 18:08