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:
2026-04-14 23:32:38 +01:00
parent d5c1cee932
commit 61a8031402
17 changed files with 1902 additions and 2 deletions

View File

@@ -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
View 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
View 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
View 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

File diff suppressed because it is too large Load Diff

29
arjz/arjz.h Normal file
View 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_ */

View File

@@ -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

View File

@@ -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
View 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
View 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

Binary file not shown.

BIN
tests/data/arj_m2.bin Normal file

Binary file not shown.

BIN
tests/data/arj_m3.bin Normal file

Binary file not shown.

BIN
tests/data/arj_m4.bin Normal file

Binary file not shown.

BIN
tests/data/arjz_default.bin Normal file

Binary file not shown.

BIN
tests/data/arjz_v55_new.bin Normal file

Binary file not shown.

BIN
tests/data/arjz_v55_old.bin Normal file

Binary file not shown.