mirror of
https://github.com/aaru-dps/Aaru.Compression.Native.git
synced 2026-07-08 18:06:12 +00:00
Add ARJ and ARJZ decompression methods and corresponding tests
- Introduced arjz.h header file with function declaration for buffer decompression. - Updated library.h to include ARJ and ARJZ decompression method declarations. - Added test cases for ARJ decompression methods (Method 1 to Method 4) in arj.cpp. - Implemented test cases for ARJZ decompression methods in arjz.cpp, including default and custom extended DEFLATE. - Copied necessary binary test data files for ARJ and ARJZ methods into the tests/data directory.
This commit is contained in:
@@ -171,7 +171,12 @@ add_library("Aaru.Compression.Native" SHARED library.c apple_rle.c apple_rle.h a
|
||||
ace/sound.c
|
||||
ace/pic.c
|
||||
ace/v1.c
|
||||
ace/v2.c)
|
||||
ace/v2.c
|
||||
arj/arj.c
|
||||
arj/arj.h
|
||||
arj/arj_fastest.c
|
||||
arjz/arjz.c
|
||||
arjz/arjz.h)
|
||||
|
||||
include(3rdparty/bzip2.cmake)
|
||||
include(3rdparty/flac.cmake)
|
||||
|
||||
257
arj/arj.c
Normal file
257
arj/arj.c
Normal file
@@ -0,0 +1,257 @@
|
||||
/*
|
||||
* This file is part of the Aaru Data Preservation Suite.
|
||||
* Copyright (c) 2019-2026 Natalia Portillo.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "arj.h"
|
||||
#include "../lha/bitio.h"
|
||||
#include "../lha/huffman.h"
|
||||
#include "../lha/lzss.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
* Parse a generic Huffman code from the bitstream.
|
||||
* width = number of bits for the symbol count.
|
||||
* specialindex = index at which to insert extra zero-run bits (-1 for none).
|
||||
*/
|
||||
static lha_prefix_code *arj_parse_code(lha_bitio *bitio, int width, int specialindex)
|
||||
{
|
||||
int num = (int)lha_bitio_next_bits(bitio, width);
|
||||
|
||||
if(num == 0)
|
||||
{
|
||||
int val = (int)lha_bitio_next_bits(bitio, width);
|
||||
lha_prefix_code *code = lha_prefix_code_new();
|
||||
|
||||
if(!code) return NULL;
|
||||
|
||||
lha_prefix_code_add(code, val, 0, 0);
|
||||
return code;
|
||||
}
|
||||
else
|
||||
{
|
||||
int *codelengths = (int *)calloc((size_t)num, sizeof(int));
|
||||
int n = 0;
|
||||
lha_prefix_code *code;
|
||||
|
||||
if(!codelengths) return NULL;
|
||||
|
||||
while(n < num)
|
||||
{
|
||||
int len = (int)lha_bitio_next_bits(bitio, 3);
|
||||
|
||||
if(len == 7)
|
||||
while(lha_bitio_next_bit(bitio)) len++;
|
||||
|
||||
codelengths[n++] = len;
|
||||
|
||||
if(n == specialindex)
|
||||
{
|
||||
int zeroes = (int)lha_bitio_next_bits(bitio, 2);
|
||||
int i;
|
||||
|
||||
for(i = 0; i < zeroes && n < num; i++) codelengths[n++] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
code = lha_prefix_code_from_lengths(codelengths, num, 16, true);
|
||||
free(codelengths);
|
||||
return code;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse the literal/length Huffman code (uses metacode compression).
|
||||
*/
|
||||
static lha_prefix_code *arj_parse_literal_code(lha_bitio *bitio)
|
||||
{
|
||||
lha_prefix_code *metacode = arj_parse_code(bitio, 5, 3);
|
||||
lha_prefix_code *code;
|
||||
int num, n;
|
||||
int *codelengths;
|
||||
|
||||
if(!metacode) return NULL;
|
||||
|
||||
num = (int)lha_bitio_next_bits(bitio, 9);
|
||||
|
||||
if(num == 0)
|
||||
{
|
||||
int val = (int)lha_bitio_next_bits(bitio, 9);
|
||||
|
||||
lha_prefix_code_free(metacode);
|
||||
code = lha_prefix_code_new();
|
||||
|
||||
if(!code) return NULL;
|
||||
|
||||
lha_prefix_code_add(code, val, 0, 0);
|
||||
return code;
|
||||
}
|
||||
|
||||
codelengths = (int *)calloc((size_t)num, sizeof(int));
|
||||
|
||||
if(!codelengths)
|
||||
{
|
||||
lha_prefix_code_free(metacode);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
n = 0;
|
||||
|
||||
while(n < num)
|
||||
{
|
||||
int c = lha_prefix_code_decode(bitio, metacode);
|
||||
|
||||
if(c < 0) break;
|
||||
|
||||
if(c <= 2)
|
||||
{
|
||||
int zeros = 0, i;
|
||||
|
||||
switch(c)
|
||||
{
|
||||
case 0:
|
||||
zeros = 1;
|
||||
break;
|
||||
case 1:
|
||||
zeros = (int)lha_bitio_next_bits(bitio, 4) + 3;
|
||||
break;
|
||||
case 2:
|
||||
zeros = (int)lha_bitio_next_bits(bitio, 9) + 20;
|
||||
break;
|
||||
}
|
||||
|
||||
if(n + zeros > num) zeros = num - n;
|
||||
|
||||
for(i = 0; i < zeros; i++) codelengths[n++] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
codelengths[n++] = c - 2;
|
||||
}
|
||||
}
|
||||
|
||||
lha_prefix_code_free(metacode);
|
||||
code = lha_prefix_code_from_lengths(codelengths, num, 16, true);
|
||||
free(codelengths);
|
||||
return code;
|
||||
}
|
||||
|
||||
/*
|
||||
* Block-based static Huffman + LZSS decompression for ARJ methods 1-3.
|
||||
* window_bits: 15 for standard ARJ, 16 for ARJZ version 51.
|
||||
*/
|
||||
static int arj_decompress_lzh(const uint8_t *in_buf, size_t in_len, uint8_t *out_buf, size_t *out_len, int window_bits)
|
||||
{
|
||||
lha_bitio bitio;
|
||||
lha_lzss lzss;
|
||||
lha_prefix_code *literalcode = NULL;
|
||||
lha_prefix_code *distancecode = NULL;
|
||||
int blocksize = 0;
|
||||
int blockpos = 0;
|
||||
size_t expected;
|
||||
int dist_width;
|
||||
|
||||
if(!in_buf || !out_buf || !out_len || in_len == 0) return -1;
|
||||
|
||||
expected = *out_len;
|
||||
dist_width = window_bits < 15 ? 4 : 5;
|
||||
|
||||
if(!lha_lzss_init(&lzss, (size_t)1 << window_bits, out_buf, expected)) return -1;
|
||||
|
||||
lha_bitio_init(&bitio, in_buf, in_len);
|
||||
|
||||
while(lzss.out_pos < expected && !lha_bitio_at_eof(&bitio))
|
||||
{
|
||||
if(blockpos >= blocksize)
|
||||
{
|
||||
blocksize = (int)lha_bitio_next_bits(&bitio, 16);
|
||||
blockpos = 0;
|
||||
|
||||
lha_prefix_code_free(literalcode);
|
||||
lha_prefix_code_free(distancecode);
|
||||
|
||||
literalcode = arj_parse_literal_code(&bitio);
|
||||
distancecode = arj_parse_code(&bitio, dist_width, -1);
|
||||
|
||||
if(!literalcode || !distancecode)
|
||||
{
|
||||
lha_prefix_code_free(literalcode);
|
||||
lha_prefix_code_free(distancecode);
|
||||
lha_lzss_cleanup(&lzss);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
blockpos++;
|
||||
|
||||
{
|
||||
int lit = lha_prefix_code_decode(&bitio, literalcode);
|
||||
|
||||
if(lit < 0) break;
|
||||
|
||||
if(lit < 0x100) { lha_lzss_emit_literal(&lzss, (uint8_t)lit); }
|
||||
else
|
||||
{
|
||||
int length = lit - 0x100 + 3;
|
||||
int bit = lha_prefix_code_decode(&bitio, distancecode);
|
||||
int offset;
|
||||
|
||||
if(bit < 0) break;
|
||||
|
||||
if(bit == 0)
|
||||
offset = 1;
|
||||
else if(bit == 1)
|
||||
offset = 2;
|
||||
else
|
||||
offset = (1 << (bit - 1)) + (int)lha_bitio_next_bits(&bitio, bit - 1) + 1;
|
||||
|
||||
lha_lzss_emit_match(&lzss, offset, length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*out_len = lzss.out_pos;
|
||||
lha_prefix_code_free(literalcode);
|
||||
lha_prefix_code_free(distancecode);
|
||||
lha_lzss_cleanup(&lzss);
|
||||
return 0;
|
||||
}
|
||||
|
||||
AARU_EXPORT int AARU_CALL arj_decompress_method1(const uint8_t *in_buf, size_t in_len, uint8_t *out_buf,
|
||||
size_t *out_len)
|
||||
{ return arj_decompress_lzh(in_buf, in_len, out_buf, out_len, 15); }
|
||||
|
||||
AARU_EXPORT int AARU_CALL arj_decompress_method2(const uint8_t *in_buf, size_t in_len, uint8_t *out_buf,
|
||||
size_t *out_len)
|
||||
{ return arj_decompress_lzh(in_buf, in_len, out_buf, out_len, 15); }
|
||||
|
||||
AARU_EXPORT int AARU_CALL arj_decompress_method3(const uint8_t *in_buf, size_t in_len, uint8_t *out_buf,
|
||||
size_t *out_len)
|
||||
{ return arj_decompress_lzh(in_buf, in_len, out_buf, out_len, 15); }
|
||||
|
||||
AARU_EXPORT int AARU_CALL arjz_decompress_method1(const uint8_t *in_buf, size_t in_len, uint8_t *out_buf,
|
||||
size_t *out_len)
|
||||
{ return arj_decompress_lzh(in_buf, in_len, out_buf, out_len, 16); }
|
||||
|
||||
AARU_EXPORT int AARU_CALL arjz_decompress_method2(const uint8_t *in_buf, size_t in_len, uint8_t *out_buf,
|
||||
size_t *out_len)
|
||||
{ return arj_decompress_lzh(in_buf, in_len, out_buf, out_len, 16); }
|
||||
|
||||
AARU_EXPORT int AARU_CALL arjz_decompress_method3(const uint8_t *in_buf, size_t in_len, uint8_t *out_buf,
|
||||
size_t *out_len)
|
||||
{ return arj_decompress_lzh(in_buf, in_len, out_buf, out_len, 16); }
|
||||
47
arj/arj.h
Normal file
47
arj/arj.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* This file is part of the Aaru Data Preservation Suite.
|
||||
* Copyright (c) 2019-2026 Natalia Portillo.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef AARU_COMPRESSION_NATIVE__ARJ_ARJ_H_
|
||||
#define AARU_COMPRESSION_NATIVE__ARJ_ARJ_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include "../library.h"
|
||||
|
||||
AARU_EXPORT int AARU_CALL arj_decompress_method1(const uint8_t *in_buf, size_t in_len, uint8_t *out_buf,
|
||||
size_t *out_len);
|
||||
|
||||
AARU_EXPORT int AARU_CALL arj_decompress_method2(const uint8_t *in_buf, size_t in_len, uint8_t *out_buf,
|
||||
size_t *out_len);
|
||||
|
||||
AARU_EXPORT int AARU_CALL arj_decompress_method3(const uint8_t *in_buf, size_t in_len, uint8_t *out_buf,
|
||||
size_t *out_len);
|
||||
|
||||
AARU_EXPORT int AARU_CALL arj_decompress_fastest(const uint8_t *in_buf, size_t in_len, uint8_t *out_buf,
|
||||
size_t *out_len);
|
||||
|
||||
AARU_EXPORT int AARU_CALL arjz_decompress_method1(const uint8_t *in_buf, size_t in_len, uint8_t *out_buf,
|
||||
size_t *out_len);
|
||||
|
||||
AARU_EXPORT int AARU_CALL arjz_decompress_method2(const uint8_t *in_buf, size_t in_len, uint8_t *out_buf,
|
||||
size_t *out_len);
|
||||
|
||||
AARU_EXPORT int AARU_CALL arjz_decompress_method3(const uint8_t *in_buf, size_t in_len, uint8_t *out_buf,
|
||||
size_t *out_len);
|
||||
|
||||
#endif /* AARU_COMPRESSION_NATIVE__ARJ_ARJ_H_ */
|
||||
118
arj/arj_fastest.c
Normal file
118
arj/arj_fastest.c
Normal file
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* This file is part of the Aaru Data Preservation Suite.
|
||||
* Copyright (c) 2019-2026 Natalia Portillo.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "../lha/bitio.h"
|
||||
#include "../lha/lzss.h"
|
||||
#include "arj.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#define ARJ_FASTEST_WINDOW_SIZE 32768
|
||||
#define ARJ_FASTEST_LEN_START 0
|
||||
#define ARJ_FASTEST_LEN_STOP 7
|
||||
#define ARJ_FASTEST_PTR_START 9
|
||||
#define ARJ_FASTEST_PTR_STOP 13
|
||||
|
||||
/*
|
||||
* Decode a variable-width length value.
|
||||
* Reads continuation bits from width LEN_START to LEN_STOP.
|
||||
* Returns 0 for literal, >0 for match length component.
|
||||
*/
|
||||
static int arj_decode_len(lha_bitio *bitio)
|
||||
{
|
||||
int val = 0;
|
||||
int w = ARJ_FASTEST_LEN_START;
|
||||
|
||||
while(w < ARJ_FASTEST_LEN_STOP)
|
||||
{
|
||||
if(!lha_bitio_next_bit(bitio)) break;
|
||||
|
||||
val += 1 << w;
|
||||
w++;
|
||||
}
|
||||
|
||||
if(w > ARJ_FASTEST_LEN_START) val += (int)lha_bitio_next_bits(bitio, w);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
/*
|
||||
* Decode a variable-width distance/pointer value.
|
||||
* Reads continuation bits from width PTR_START to PTR_STOP.
|
||||
*/
|
||||
static int arj_decode_ptr(lha_bitio *bitio)
|
||||
{
|
||||
int val = 0;
|
||||
int w = ARJ_FASTEST_PTR_START;
|
||||
|
||||
while(w < ARJ_FASTEST_PTR_STOP)
|
||||
{
|
||||
if(!lha_bitio_next_bit(bitio)) break;
|
||||
|
||||
val += 1 << w;
|
||||
w++;
|
||||
}
|
||||
|
||||
val += (int)lha_bitio_next_bits(bitio, w);
|
||||
return val;
|
||||
}
|
||||
|
||||
/*
|
||||
* ARJ method 4 ("Fastest") decompression.
|
||||
* LZSS with variable-width Golomb-Rice codes for length and distance.
|
||||
* 32KB sliding window, MSB-first bit extraction.
|
||||
*/
|
||||
AARU_EXPORT int AARU_CALL arj_decompress_fastest(const uint8_t *in_buf, size_t in_len, uint8_t *out_buf,
|
||||
size_t *out_len)
|
||||
{
|
||||
lha_bitio bitio;
|
||||
lha_lzss lzss;
|
||||
size_t expected;
|
||||
|
||||
if(!in_buf || !out_buf || !out_len || in_len == 0) return -1;
|
||||
|
||||
expected = *out_len;
|
||||
|
||||
if(!lha_lzss_init(&lzss, ARJ_FASTEST_WINDOW_SIZE, out_buf, expected)) return -1;
|
||||
|
||||
lha_bitio_init(&bitio, in_buf, in_len);
|
||||
|
||||
while(lzss.out_pos < expected && !lha_bitio_at_eof(&bitio))
|
||||
{
|
||||
int c = arj_decode_len(&bitio);
|
||||
|
||||
if(c == 0)
|
||||
{
|
||||
/* Literal byte */
|
||||
uint8_t byte = (uint8_t)lha_bitio_next_bits(&bitio, 8);
|
||||
lha_lzss_emit_literal(&lzss, byte);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Match: length = c - 1 + threshold(3) = c + 2 */
|
||||
int length = c + 2;
|
||||
int offset = arj_decode_ptr(&bitio) + 1;
|
||||
|
||||
lha_lzss_emit_match(&lzss, offset, length);
|
||||
}
|
||||
}
|
||||
|
||||
*out_len = lzss.out_pos;
|
||||
lha_lzss_cleanup(&lzss);
|
||||
return 0;
|
||||
}
|
||||
1123
arjz/arjz.c
Normal file
1123
arjz/arjz.c
Normal file
File diff suppressed because it is too large
Load Diff
29
arjz/arjz.h
Normal file
29
arjz/arjz.h
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* This file is part of the Aaru Data Preservation Suite.
|
||||
* Copyright (c) 2019-2026 Natalia Portillo.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef AARU_COMPRESSION_NATIVE__ARJZ_ARJZ_H_
|
||||
#define AARU_COMPRESSION_NATIVE__ARJZ_ARJZ_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include "../library.h"
|
||||
|
||||
AARU_EXPORT int AARU_CALL arjz_decompress_buffer(const uint8_t *in_buf, size_t in_len, uint8_t *out_buf,
|
||||
size_t *out_len, size_t orig_size);
|
||||
|
||||
#endif /* AARU_COMPRESSION_NATIVE__ARJZ_ARJZ_H_ */
|
||||
25
library.h
25
library.h
@@ -240,4 +240,29 @@ AARU_EXPORT int AARU_CALL ace_decompress_lz77(const uint8_t *in_buf, size_t in_l
|
||||
// ACE v2 (Blocked) decompression
|
||||
AARU_EXPORT int AARU_CALL ace_decompress_blocked(const uint8_t *in_buf, size_t in_len, uint8_t *out_buf, size_t *out_len, int dic_bits);
|
||||
|
||||
// ARJ Method 1 (LZH, most compression)
|
||||
AARU_EXPORT int AARU_CALL arj_decompress_method1(const uint8_t *in_buf, size_t in_len, uint8_t *out_buf, size_t *out_len);
|
||||
|
||||
// ARJ Method 2 (LZH, medium compression)
|
||||
AARU_EXPORT int AARU_CALL arj_decompress_method2(const uint8_t *in_buf, size_t in_len, uint8_t *out_buf, size_t *out_len);
|
||||
|
||||
// ARJ Method 3 (LZH, fast compression)
|
||||
AARU_EXPORT int AARU_CALL arj_decompress_method3(const uint8_t *in_buf, size_t in_len, uint8_t *out_buf, size_t *out_len);
|
||||
|
||||
// ARJ Method 4 (Fastest, variable-width LZSS)
|
||||
AARU_EXPORT int AARU_CALL arj_decompress_fastest(const uint8_t *in_buf, size_t in_len, uint8_t *out_buf, size_t *out_len);
|
||||
|
||||
// ARJZ Method 1 (LZH, 64KB window)
|
||||
AARU_EXPORT int AARU_CALL arjz_decompress_method1(const uint8_t *in_buf, size_t in_len, uint8_t *out_buf, size_t *out_len);
|
||||
|
||||
// ARJZ Method 2 (LZH, 64KB window)
|
||||
AARU_EXPORT int AARU_CALL arjz_decompress_method2(const uint8_t *in_buf, size_t in_len, uint8_t *out_buf, size_t *out_len);
|
||||
|
||||
// ARJZ Method 3 (LZH, 64KB window)
|
||||
AARU_EXPORT int AARU_CALL arjz_decompress_method3(const uint8_t *in_buf, size_t in_len, uint8_t *out_buf, size_t *out_len);
|
||||
|
||||
// ARJZ custom extended DEFLATE decompression
|
||||
AARU_EXPORT int AARU_CALL arjz_decompress_buffer(const uint8_t *in_buf, size_t in_len, uint8_t *out_buf, size_t *out_len,
|
||||
size_t orig_size);
|
||||
|
||||
#endif // AARU_COMPRESSION_NATIVE_LIBRARY_H
|
||||
|
||||
@@ -96,11 +96,31 @@ file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/data/ace_v1_lz77.bin
|
||||
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/data/ace_v2_blocked.bin
|
||||
DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/data/)
|
||||
|
||||
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/data/arj_m1.bin
|
||||
DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/data/)
|
||||
|
||||
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/data/arj_m2.bin
|
||||
DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/data/)
|
||||
|
||||
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/data/arj_m3.bin
|
||||
DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/data/)
|
||||
|
||||
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/data/arj_m4.bin
|
||||
DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/data/)
|
||||
|
||||
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/data/arjz_default.bin
|
||||
DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/data/)
|
||||
|
||||
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/data/arjz_v55_new.bin
|
||||
DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/data/)
|
||||
|
||||
# 'Google_Tests_run' is the target name
|
||||
# 'test1.cpp tests2.cpp' are source files with tests
|
||||
add_executable(tests_run apple_rle.cpp crc32.c crc32.h adc.cpp bzip2.cpp lzip.cpp lzfse.cpp zstd.cpp lzma.cpp flac.cpp lz4.cpp
|
||||
zoo/lzd.cpp arc/pack.cpp lh5.cpp arc/squeeze.cpp arc/crunch.cpp arc/squash.cpp pak/crush.cpp
|
||||
pak/distill.cpp ha.cpp xz.cpp
|
||||
lha/lh_static.cpp lha/lh1.cpp lha/larc.cpp lha/lh_old.cpp
|
||||
ace/ace.cpp)
|
||||
ace/ace.cpp
|
||||
arj/arj.cpp
|
||||
arjz/arjz.cpp)
|
||||
target_link_libraries(tests_run gtest gtest_main "Aaru.Compression.Native")
|
||||
|
||||
175
tests/arj/arj.cpp
Normal file
175
tests/arj/arj.cpp
Normal file
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
* This file is part of the Aaru Data Preservation Suite.
|
||||
* Copyright (c) 2019-2026 Natalia Portillo.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <climits>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "../../library.h"
|
||||
#include "../crc32.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#define EXPECTED_CRC32 0x66007DBA
|
||||
#define EXPECTED_ORIGSIZE 152089
|
||||
|
||||
/* ---- Method 1 ---- */
|
||||
|
||||
static const uint8_t *buffer_m1;
|
||||
|
||||
class arj_m1Fixture : public ::testing::Test
|
||||
{
|
||||
protected:
|
||||
void SetUp()
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
char filename[PATH_MAX];
|
||||
getcwd(path, PATH_MAX);
|
||||
snprintf(filename, PATH_MAX, "%s/data/arj_m1.bin", path);
|
||||
FILE *file = fopen(filename, "rb");
|
||||
buffer_m1 = (const uint8_t *)malloc(55125);
|
||||
fread((void *)buffer_m1, 1, 55125, file);
|
||||
fclose(file);
|
||||
}
|
||||
void TearDown() { free((void *)buffer_m1); }
|
||||
};
|
||||
|
||||
TEST_F(arj_m1Fixture, arj_method1)
|
||||
{
|
||||
size_t destLen = EXPECTED_ORIGSIZE;
|
||||
auto *outBuf = (uint8_t *)malloc(EXPECTED_ORIGSIZE);
|
||||
|
||||
auto err = arj_decompress_method1(buffer_m1, 55125, outBuf, &destLen);
|
||||
|
||||
EXPECT_EQ(err, 0);
|
||||
EXPECT_EQ(destLen, (size_t)EXPECTED_ORIGSIZE);
|
||||
|
||||
auto crc = crc32_data(outBuf, EXPECTED_ORIGSIZE);
|
||||
free(outBuf);
|
||||
EXPECT_EQ(crc, EXPECTED_CRC32);
|
||||
}
|
||||
|
||||
/* ---- Method 2 ---- */
|
||||
|
||||
static const uint8_t *buffer_m2;
|
||||
|
||||
class arj_m2Fixture : public ::testing::Test
|
||||
{
|
||||
protected:
|
||||
void SetUp()
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
char filename[PATH_MAX];
|
||||
getcwd(path, PATH_MAX);
|
||||
snprintf(filename, PATH_MAX, "%s/data/arj_m2.bin", path);
|
||||
FILE *file = fopen(filename, "rb");
|
||||
buffer_m2 = (const uint8_t *)malloc(55721);
|
||||
fread((void *)buffer_m2, 1, 55721, file);
|
||||
fclose(file);
|
||||
}
|
||||
void TearDown() { free((void *)buffer_m2); }
|
||||
};
|
||||
|
||||
TEST_F(arj_m2Fixture, arj_method2)
|
||||
{
|
||||
size_t destLen = EXPECTED_ORIGSIZE;
|
||||
auto *outBuf = (uint8_t *)malloc(EXPECTED_ORIGSIZE);
|
||||
|
||||
auto err = arj_decompress_method2(buffer_m2, 55721, outBuf, &destLen);
|
||||
|
||||
EXPECT_EQ(err, 0);
|
||||
EXPECT_EQ(destLen, (size_t)EXPECTED_ORIGSIZE);
|
||||
|
||||
auto crc = crc32_data(outBuf, EXPECTED_ORIGSIZE);
|
||||
free(outBuf);
|
||||
EXPECT_EQ(crc, EXPECTED_CRC32);
|
||||
}
|
||||
|
||||
/* ---- Method 3 ---- */
|
||||
|
||||
static const uint8_t *buffer_m3;
|
||||
|
||||
class arj_m3Fixture : public ::testing::Test
|
||||
{
|
||||
protected:
|
||||
void SetUp()
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
char filename[PATH_MAX];
|
||||
getcwd(path, PATH_MAX);
|
||||
snprintf(filename, PATH_MAX, "%s/data/arj_m3.bin", path);
|
||||
FILE *file = fopen(filename, "rb");
|
||||
buffer_m3 = (const uint8_t *)malloc(59190);
|
||||
fread((void *)buffer_m3, 1, 59190, file);
|
||||
fclose(file);
|
||||
}
|
||||
void TearDown() { free((void *)buffer_m3); }
|
||||
};
|
||||
|
||||
TEST_F(arj_m3Fixture, arj_method3)
|
||||
{
|
||||
size_t destLen = EXPECTED_ORIGSIZE;
|
||||
auto *outBuf = (uint8_t *)malloc(EXPECTED_ORIGSIZE);
|
||||
|
||||
auto err = arj_decompress_method3(buffer_m3, 59190, outBuf, &destLen);
|
||||
|
||||
EXPECT_EQ(err, 0);
|
||||
EXPECT_EQ(destLen, (size_t)EXPECTED_ORIGSIZE);
|
||||
|
||||
auto crc = crc32_data(outBuf, EXPECTED_ORIGSIZE);
|
||||
free(outBuf);
|
||||
EXPECT_EQ(crc, EXPECTED_CRC32);
|
||||
}
|
||||
|
||||
/* ---- Method 4 (Fastest) ---- */
|
||||
|
||||
static const uint8_t *buffer_m4;
|
||||
|
||||
class arj_m4Fixture : public ::testing::Test
|
||||
{
|
||||
protected:
|
||||
void SetUp()
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
char filename[PATH_MAX];
|
||||
getcwd(path, PATH_MAX);
|
||||
snprintf(filename, PATH_MAX, "%s/data/arj_m4.bin", path);
|
||||
FILE *file = fopen(filename, "rb");
|
||||
buffer_m4 = (const uint8_t *)malloc(66519);
|
||||
fread((void *)buffer_m4, 1, 66519, file);
|
||||
fclose(file);
|
||||
}
|
||||
void TearDown() { free((void *)buffer_m4); }
|
||||
};
|
||||
|
||||
TEST_F(arj_m4Fixture, arj_method4_fastest)
|
||||
{
|
||||
size_t destLen = EXPECTED_ORIGSIZE;
|
||||
auto *outBuf = (uint8_t *)malloc(EXPECTED_ORIGSIZE);
|
||||
|
||||
auto err = arj_decompress_fastest(buffer_m4, 66519, outBuf, &destLen);
|
||||
|
||||
EXPECT_EQ(err, 0);
|
||||
EXPECT_EQ(destLen, (size_t)EXPECTED_ORIGSIZE);
|
||||
|
||||
auto crc = crc32_data(outBuf, EXPECTED_ORIGSIZE);
|
||||
free(outBuf);
|
||||
EXPECT_EQ(crc, EXPECTED_CRC32);
|
||||
}
|
||||
101
tests/arjz/arjz.cpp
Normal file
101
tests/arjz/arjz.cpp
Normal file
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* This file is part of the Aaru Data Preservation Suite.
|
||||
* Copyright (c) 2019-2026 Natalia Portillo.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <climits>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "../../library.h"
|
||||
#include "../crc32.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#define EXPECTED_CRC32 0x66007DBA
|
||||
#define EXPECTED_ORIGSIZE 152089
|
||||
|
||||
static const uint8_t *buffer_arjz;
|
||||
|
||||
class arjz_defaultFixture : public ::testing::Test
|
||||
{
|
||||
protected:
|
||||
void SetUp()
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
char filename[PATH_MAX];
|
||||
getcwd(path, PATH_MAX);
|
||||
snprintf(filename, PATH_MAX, "%s/data/arjz_default.bin", path);
|
||||
FILE *file = fopen(filename, "rb");
|
||||
buffer_arjz = (const uint8_t *)malloc(52577);
|
||||
fread((void *)buffer_arjz, 1, 52577, file);
|
||||
fclose(file);
|
||||
}
|
||||
void TearDown() { free((void *)buffer_arjz); }
|
||||
};
|
||||
|
||||
TEST_F(arjz_defaultFixture, arjz_default)
|
||||
{
|
||||
size_t destLen = EXPECTED_ORIGSIZE;
|
||||
auto *outBuf = (uint8_t *)malloc(EXPECTED_ORIGSIZE);
|
||||
|
||||
auto err = arjz_decompress_method1(buffer_arjz, 52577, outBuf, &destLen);
|
||||
|
||||
EXPECT_EQ(err, 0);
|
||||
EXPECT_EQ(destLen, (size_t)EXPECTED_ORIGSIZE);
|
||||
|
||||
auto crc = crc32_data(outBuf, EXPECTED_ORIGSIZE);
|
||||
free(outBuf);
|
||||
EXPECT_EQ(crc, EXPECTED_CRC32);
|
||||
}
|
||||
|
||||
/* ---- ARJZ v55 (custom extended DEFLATE) ---- */
|
||||
|
||||
static const uint8_t *buffer_arjz_v55;
|
||||
|
||||
class arjz_v55Fixture : public ::testing::Test
|
||||
{
|
||||
protected:
|
||||
void SetUp()
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
char filename[PATH_MAX];
|
||||
getcwd(path, PATH_MAX);
|
||||
snprintf(filename, PATH_MAX, "%s/data/arjz_v55_new.bin", path);
|
||||
FILE *file = fopen(filename, "rb");
|
||||
buffer_arjz_v55 = (const uint8_t *)malloc(52010);
|
||||
fread((void *)buffer_arjz_v55, 1, 52010, file);
|
||||
fclose(file);
|
||||
}
|
||||
void TearDown() { free((void *)buffer_arjz_v55); }
|
||||
};
|
||||
|
||||
TEST_F(arjz_v55Fixture, arjz_v55_deflatez)
|
||||
{
|
||||
size_t destLen = EXPECTED_ORIGSIZE;
|
||||
auto *outBuf = (uint8_t *)malloc(EXPECTED_ORIGSIZE);
|
||||
|
||||
auto err = arjz_decompress_buffer(buffer_arjz_v55, 52010, outBuf, &destLen, EXPECTED_ORIGSIZE);
|
||||
|
||||
EXPECT_EQ(err, 0);
|
||||
EXPECT_EQ(destLen, (size_t)EXPECTED_ORIGSIZE);
|
||||
|
||||
auto crc = crc32_data(outBuf, EXPECTED_ORIGSIZE);
|
||||
free(outBuf);
|
||||
EXPECT_EQ(crc, EXPECTED_CRC32);
|
||||
}
|
||||
BIN
tests/data/arj_m1.bin
Normal file
BIN
tests/data/arj_m1.bin
Normal file
Binary file not shown.
BIN
tests/data/arj_m2.bin
Normal file
BIN
tests/data/arj_m2.bin
Normal file
Binary file not shown.
BIN
tests/data/arj_m3.bin
Normal file
BIN
tests/data/arj_m3.bin
Normal file
Binary file not shown.
BIN
tests/data/arj_m4.bin
Normal file
BIN
tests/data/arj_m4.bin
Normal file
Binary file not shown.
BIN
tests/data/arjz_default.bin
Normal file
BIN
tests/data/arjz_default.bin
Normal file
Binary file not shown.
BIN
tests/data/arjz_v55_new.bin
Normal file
BIN
tests/data/arjz_v55_new.bin
Normal file
Binary file not shown.
BIN
tests/data/arjz_v55_old.bin
Normal file
BIN
tests/data/arjz_v55_old.bin
Normal file
Binary file not shown.
Reference in New Issue
Block a user