mirror of
https://github.com/aaru-dps/Aaru.Compression.Native.git
synced 2025-12-16 19:24:31 +00:00
Add Apple RLE algorithm.
This commit is contained in:
@@ -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
97
apple_rle.c
Normal 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
27
apple_rle.h
Normal 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_
|
||||
24
library.c
24
library.c
@@ -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"); }
|
||||
|
||||
54
library.h
54
library.h
@@ -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
|
||||
|
||||
@@ -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
83
tests/apple_rle.cpp
Normal 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
55
tests/crc32.c
Normal 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
30
tests/crc32.h
Normal 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
BIN
tests/data/apple_rle.bin
Normal file
Binary file not shown.
Reference in New Issue
Block a user