Skip to content

Commit

Permalink
Convert to all C++
Browse files Browse the repository at this point in the history
  • Loading branch information
mtheall committed Oct 10, 2017
1 parent dca4527 commit 471471e
Show file tree
Hide file tree
Showing 8 changed files with 959 additions and 1,405 deletions.
6 changes: 3 additions & 3 deletions Makefile.am
Expand Up @@ -6,12 +6,12 @@ bin_PROGRAMS = tex3ds

tex3ds_SOURCES = source/atlas.cpp \
source/encode.cpp \
source/huff.c \
source/lzss.c \
source/huff.cpp \
source/lzss.cpp \
source/magick_compat.cpp \
source/main.cpp \
source/rg_etc1.cpp \
source/rle.c
source/rle.cpp

tex3ds_LDADD = $(ImageMagick_LIBS)
AM_CPPFLAGS = -I$(srcdir)/include -D_GNU_SOURCE $(ImageMagick_CFLAGS)
Expand Down
20 changes: 2 additions & 18 deletions configure.ac
Expand Up @@ -10,11 +10,6 @@ AM_INIT_AUTOMAKE

# Checks for programs.
AC_PROG_CXX
AC_PROG_CC

AC_LANG_PUSH([C])
AX_CHECK_COMPILE_FLAG([-std=c99], [CFLAGS+=" -std=c99"])
AC_LANG_POP()

AC_LANG_PUSH([C++])
AX_CHECK_COMPILE_FLAG([-Wall], [CPPFLAGS+=" -Wall"])
Expand Down Expand Up @@ -44,21 +39,10 @@ PKG_CONFIG=$_save_PKG_CONFIG[]dnl
PKG_CHECK_MODULES_STATIC(ImageMagick, [Magick++ >= 6.0.0])

# Checks for header files.
AC_CHECK_HEADERS([limits.h stddef.h stdint.h stdlib.h string.h unistd.h])

# Checks for typedefs, structures, and compiler characteristics.
AC_CHECK_HEADER_STDBOOL
AC_C_INLINE
AC_TYPE_OFF_T
AC_TYPE_SIZE_T
AC_TYPE_SSIZE_T
AC_TYPE_UINT16_T
AC_TYPE_UINT32_T
AC_TYPE_UINT64_T
AC_TYPE_UINT8_T
AC_CHECK_HEADERS([unistd.h])

# Checks for library functions.
AC_CHECK_FUNCS([memrchr memset pow strcasecmp])
AC_CHECK_FUNCS([strcasecmp])

AC_CONFIG_FILES([Makefile])
AC_OUTPUT
152 changes: 25 additions & 127 deletions include/compress.h
Expand Up @@ -22,200 +22,98 @@
*/
#pragma once

/** @brief Compression header size */
#define COMPRESSION_HEADER_SIZE 8

#ifdef __cplusplus
#include <cassert>
extern "C"
{
#else
#include <assert.h>
#include <stddef.h>
#include <stdint.h>
#endif
#include <cstddef>
#include <cstdint>
#include <vector>

/** @brief LZSS/LZ10 compression
* @param[in] src Source buffer
* @param[in] len Source length
* @param[out] outlen Output length
* @returns Compressed buffer
* @note Caller must `free()` the output buffer
*/
void* lzss_encode(const void *src, size_t len, size_t *outlen);
std::vector<uint8_t> lzssEncode(const void *src, size_t len);

/** @brief LZSS/LZ10 decompression
* @param[in] src Source buffer
* @param[out] dst Destination buffer
* @param[in] len Source length
* @note The output buffer must be large enough to hold the decompressed data
*/
void lzss_decode(const void *src, void *dst, size_t len);
void lzssDecode(const void *src, void *dst, size_t len);

/** @brief LZ11 compression
* @param[in] src Source buffer
* @param[in] len Source length
* @param[out] outlen Output length
* @returns Compressed buffer
* @note Caller must `free()` the output buffer
*/
void* lz11_encode(const void *src, size_t len, size_t *outlen);
std::vector<uint8_t> lz11Encode(const void *src, size_t len);

/** @brief LZ11 decompression
* @param[in] src Source buffer
* @param[out] dst Destination buffer
* @param[in] len Source length
* @note The output buffer must be large enough to hold the decompressed data
*/
void lz11_decode(const void *src, void *dst, size_t len);
void lz11Decode(const void *src, void *dst, size_t len);

/** @brief Run-length encoding compression
* @param[in] src Source buffer
* @param[in] len Source length
* @param[out] outlen Output length
* @returns Compressed buffer
* @note Caller must `free()` the output buffer
*/
void* rle_encode(const void *src, size_t len, size_t *outlen);
std::vector<uint8_t> rleEncode(const void *src, size_t len);

/** @brief Run-length encoding decompression
* @param[in] src Source buffer
* @param[out] dst Destination buffer
* @param[in] len Source length
* @note The output buffer must be large enough to hold the decompressed data
*/
void rle_decode(const void *src, void *dst, size_t len);
void rleDecode(const void *src, void *dst, size_t len);

/** @brief Huffman compression
* @param[in] src Source buffer
* @param[in] len Source length
* @param[out] outlen Output length
* @returns Compressed buffer
* @note Caller must `free()` the output buffer
*/
void* huff_encode(const void *src, size_t len, size_t *outlen);
std::vector<uint8_t> huffEncode(const void *src, size_t len);

/** @brief Huffman decompression
* @param[in] src Source buffer
* @param[out] dst Destination buffer
* @param[in] len Source length
* @note The output buffer must be large enough to hold the decompressed data
*/
void huff_decode(const void *src, void *dst, size_t len);
void huffDecode(const void *src, void *dst, size_t len);

namespace
{

/** @brief Output a GBA-style compression header
* @param[out] header Output header
* @param[in] type Compression type
* @param[in] size Uncompressed data size
* @returns Size of the compression header
*/
static inline size_t
compression_header(uint8_t header[COMPRESSION_HEADER_SIZE], uint8_t type, size_t size)
inline void
compressionHeader(std::vector<uint8_t> &buffer, uint8_t type, size_t size)
{
assert (!(type & 0x80));

header[0] = type;
header[1] = size;
header[2] = size >> 8;
header[3] = size >> 16;
buffer.push_back(type);
buffer.push_back(size >> 0);
buffer.push_back(size >> 8);
buffer.push_back(size >> 16);

if(size >= 0x1000000)
{
header[0] |= 0x80;
header[4] = size >> 24;
header[5] = 0; /* Reserved */
header[6] = 0; /* Reserved */
header[7] = 0; /* Reserved */

return 8;
}

return 4;
}

#ifdef COMPRESSION_INTERNAL
#include <stdlib.h>
#include <string.h>

/** @brief Output buffer */
typedef struct
{
uint8_t *data; ///< Output data
size_t len; ///< Data length
size_t limit; ///< Maximum data length
} buffer_t;

/** @brief Initialize buffer_t
* @param[out] buffer Output buffer
*/
static inline void
buffer_init(buffer_t *buffer)
{
buffer->data = NULL;
buffer->len = 0;
buffer->limit = 0;
}

/** @brief Append to a buffer
* @param[in,out] buffer Output buffer
* @param[in] data Data to append
* @param[in] len Length of data to append
* @retval 0 success
* @retval -1 failure
*/
static inline int
buffer_push(buffer_t *buffer, const uint8_t *data, size_t len)
{
if(len + buffer->len > buffer->limit)
{
size_t limit = (len + buffer->len + 0x0FFF) & ~0x0FFF;
uint8_t *tmp = realloc(buffer->data, limit);
if(tmp)
{
buffer->limit = limit;
buffer->data = tmp;
}
else
return -1;
}

if(data != NULL)
memcpy(buffer->data + buffer->len, data, len);
else
memset(buffer->data + buffer->len, 0, len);

buffer->len += len;
return 0;
}

/** @brief Pad an output buffer
* @param[in,out] buffer Output buffer to pad
* @param[in] padding Alignment to pad
* @retval 0 success
* @retval -1 failure
*/
static inline int
buffer_pad(buffer_t *buffer, size_t padding)
{
if(buffer->len % padding != 0)
{
size_t len = padding - (buffer->len % padding);
return buffer_push(buffer, NULL, len);
buffer[buffer.size() - 4] |= 0x80;
buffer.push_back(size >> 24);
buffer.push_back(0); /* Reserved */
buffer.push_back(0); /* Reserved */
buffer.push_back(0); /* Reserved */
}

return 0;
}

/** @brief Destroy an output buffer
* @param[in] buffer Output buffer to destroy
*/
static inline void
buffer_destroy(buffer_t *buffer)
{
free(buffer->data);
}
#endif

#ifdef __cplusplus
}
#endif

0 comments on commit 471471e

Please sign in to comment.