Add Apple RLE algorithm.

This commit is contained in:
2021-10-14 04:37:48 +01:00
parent 05dbda33ab
commit 1a9a76b2d3
10 changed files with 371 additions and 8 deletions

View File

@@ -71,6 +71,6 @@ if("${CMAKE_BUILD_TYPE}" MATCHES "Release")
endif()
endif()
add_library("Aaru.Compression.Native" SHARED library.c)
add_library("Aaru.Compression.Native" SHARED library.c apple_rle.c apple_rle.h)
#add_subdirectory(tests)
add_subdirectory(tests)

97
apple_rle.c Normal file
View File

@@ -0,0 +1,97 @@
/*
* This file is part of the Aaru Data Preservation Suite.
* Copyright (c) 2019-2021 Natalia Portillo.
* Copyright © 2018-2019 David Ryskalczyk
*
* 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 <stdbool.h>
#include <stdint.h>
#include "library.h"
#include "apple_rle.h"
// readonly Stream _inStream;
static int32_t count;
static bool nextA; // true if A, false if B
static uint8_t repeatedByteA, repeatedByteB;
static bool repeatMode; // true if we're repeating, false if we're just copying
/// <summary>Initializes a decompressor for the specified stream</summary>
/// <param name="stream">Stream containing the compressed data</param>
AARU_EXPORT void AARU_CALL apple_rle_reset()
{
repeatedByteA = repeatedByteB = 0;
count = 0;
nextA = true;
repeatMode = false;
}
/// <summary>Decompresses a byte</summary>
/// <returns>Decompressed byte</returns>
AARU_EXPORT int32_t AARU_CALL apple_rle_produce_byte(const uint8_t* buffer, int32_t length, int32_t* position)
{
if(repeatMode && count > 0)
{
count--;
if(nextA)
{
nextA = false;
return repeatedByteA;
}
nextA = true;
return repeatedByteB;
}
if(!repeatMode && count > 0)
{
count--;
return buffer[(*position)++];
}
if(*position == length) return -1;
while(true)
{
uint8_t b1 = buffer[(*position)++];
uint8_t b2 = buffer[(*position)++];
int16_t s = (int16_t)((b1 << 8) | b2);
if(s == 0 || s >= DART_CHUNK || s <= -DART_CHUNK) continue;
if(s < 0)
{
repeatMode = true;
repeatedByteA = buffer[(*position)++];
repeatedByteB = buffer[(*position)++];
count = (-s * 2) - 1;
nextA = false;
return repeatedByteA;
}
if(s <= 0) continue;
repeatMode = false;
count = (s * 2) - 1;
return buffer[(*position)++];
}
}

27
apple_rle.h Normal file
View File

@@ -0,0 +1,27 @@
/*
* This file is part of the Aaru Data Preservation Suite.
* Copyright (c) 2019-2021 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_CHECKSUMS_NATIVE__APPLE_RLE_H_
#define AARU_CHECKSUMS_NATIVE__APPLE_RLE_H_
#define DART_CHUNK 20960
AARU_EXPORT void AARU_CALL apple_rle_reset();
AARU_EXPORT int32_t AARU_CALL apple_rle_produce_byte(const uint8_t* buffer, int32_t length, int32_t* position);
#endif // AARU_CHECKSUMS_NATIVE__APPLE_RLE_H_

View File

@@ -1,7 +1,23 @@
#include "library.h"
/*
* This file is part of the Aaru Data Preservation Suite.
* Copyright (c) 2019-2021 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 <stdio.h>
void hello(void) {
printf("Hello, World!\n");
}
#include "library.h"
void hello(void) { printf("Hello, World!\n"); }

View File

@@ -1,5 +1,57 @@
/*
* This file is part of the Aaru Data Preservation Suite.
* Copyright (c) 2019-2021 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_LIBRARY_H
#define AARU_COMPRESSION_NATIVE_LIBRARY_H
#ifdef __cplusplus
#define EXTERNC extern "C"
#else
#define EXTERNC
#endif
#endif//AARU_COMPRESSION_NATIVE_LIBRARY_H
#if defined(_WIN32)
#define AARU_CALL __stdcall
#define AARU_EXPORT EXTERNC __declspec(dllexport)
#define AARU_LOCAL
#ifndef PATH_MAX
#define PATH_MAX _MAX_PATH
#endif
#else
#define AARU_CALL
#if defined(__APPLE__)
#define AARU_EXPORT EXTERNC __attribute__((visibility("default")))
#define AARU_LOCAL __attribute__((visibility("hidden")))
#else
#if __GNUC__ >= 4
#define AARU_EXPORT EXTERNC __attribute__((visibility("default")))
#define AARU_LOCAL __attribute__((visibility("hidden")))
#else
#define AARU_EXPORT EXTERNC
#define AARU_LOCAL
#endif
#endif
#endif
#ifdef _MSC_VER
#define FORCE_INLINE static inline
#else
#define FORCE_INLINE static inline __attribute__((always_inline))
#endif
#endif // AARU_COMPRESSION_NATIVE_LIBRARY_H

View File

@@ -9,7 +9,10 @@ project(tests)
add_subdirectory(lib)
include_directories(${gtest_SOURCE_DIR}/include ${gtest_SOURCE_DIR})
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/data/apple_rle.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 "")
add_executable(tests_run apple_rle.cpp crc32.c crc32.h)
target_link_libraries(tests_run gtest gtest_main "Aaru.Compression.Native")

83
tests/apple_rle.cpp Normal file
View File

@@ -0,0 +1,83 @@
/*
* This file is part of the Aaru Data Preservation Suite.
* Copyright (c) 2019-2021 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 <cstdint>
#include <cstring>
#include "../library.h"
#include "../apple_rle.h"
#include "crc32.h"
#include "gtest/gtest.h"
#define EXPECTED_CRC32 0x3525ef06
static const uint8_t* buffer;
class apple_rleFixture : public ::testing::Test
{
public:
apple_rleFixture()
{
// initialization;
// can also be done in SetUp()
}
protected:
void SetUp()
{
char path[PATH_MAX];
char filename[PATH_MAX];
getcwd(path, PATH_MAX);
snprintf(filename, PATH_MAX, "%s/data/apple_rle.bin", path);
FILE* file = fopen(filename, "rb");
buffer = (const uint8_t*)malloc(1102);
fread((void*)buffer, 1, 1102, file);
fclose(file);
}
void TearDown() {
free((void*)buffer);
}
~apple_rleFixture()
{
// resources cleanup, no exceptions allowed
}
// shared user data
};
TEST_F(apple_rleFixture, apple_rle)
{
auto *outBuf = (uint8_t*)malloc(20960);
int32_t position = 0;
apple_rle_reset();
for(int i = 0; i < 20960; i++)
outBuf[i] = (uint8_t)apple_rle_produce_byte(buffer, 1102, &position);
auto crc = crc32_data(outBuf, 20960);
free(outBuf);
EXPECT_EQ(crc, EXPECTED_CRC32);
}

55
tests/crc32.c Normal file
View File

@@ -0,0 +1,55 @@
/*
* This file is part of the Aaru Data Preservation Suite.
* Copyright (c) 2019-2021 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/>.
*/
#ifdef __cplusplus
extern "C"
{
#endif
#include <stdint.h>
#define CRC32_ISO_POLY 0xEDB88320
#define CRC32_ISO_SEED 0xFFFFFFFF
uint32_t crc32_data(const uint8_t *data, uint32_t len)
{
uint32_t localHashInt = CRC32_ISO_SEED;
uint32_t localTable[256];
int i, j;
for(i = 0; i < 256; i++)
{
uint32_t entry = (uint32_t)i;
for(j = 0; j < 8; j++)
if((entry & 1) == 1)
entry = (entry >> 1) ^ CRC32_ISO_POLY;
else
entry >>= 1;
localTable[i] = entry;
}
for(i = 0; i < len; i++)
localHashInt = (localHashInt >> 8) ^ localTable[data[i] ^ (localHashInt & 0xff)];
localHashInt ^= CRC32_ISO_SEED;
return localHashInt;
}
#ifdef __cplusplus
}
#endif

30
tests/crc32.h Normal file
View File

@@ -0,0 +1,30 @@
/*
* This file is part of the Aaru Data Preservation Suite.
* Copyright (c) 2019-2021 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_CHECKSUMS_NATIVE_TESTS_CRC32_H_
#define AARU_CHECKSUMS_NATIVE_TESTS_CRC32_H_
#ifdef __cplusplus
extern "C"
{
#endif
uint32_t crc32_data(const uint8_t* data, uint32_t len);
#ifdef __cplusplus
}
#endif
#endif // AARU_CHECKSUMS_NATIVE_TESTS_CRC32_H_

BIN
tests/data/apple_rle.bin Normal file

Binary file not shown.