Permalink
Fetching contributors…
Cannot retrieve contributors at this time
100 lines (81 sloc) 3.47 KB
/*********************************************************************
Blosc - Blocked Shuffling and Compression Library
Author: Francesc Alted <francesc@blosc.org>
See LICENSES/BLOSC.txt for details about copyright and rights to use.
**********************************************************************/
/* Generic (non-hardware-accelerated) shuffle/unshuffle routines.
These are used when hardware-accelerated functions aren't available
for a particular platform; they are also used by the hardware-
accelerated functions to handle any remaining elements in a block
which isn't a multiple of the hardware's vector size. */
#ifndef SHUFFLE_GENERIC_H
#define SHUFFLE_GENERIC_H
#include "blosc-common.h"
#include <stdlib.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
Generic (non-hardware-accelerated) shuffle routine.
This is the pure element-copying nested loop. It is used by the
generic shuffle implementation and also by the vectorized shuffle
implementations to process any remaining elements in a block which
is not a multiple of (type_size * vector_size).
*/
static void shuffle_generic_inline(const size_t type_size,
const size_t vectorizable_blocksize, const size_t blocksize,
const uint8_t* const _src, uint8_t* const _dest)
{
size_t i, j;
/* Calculate the number of elements in the block. */
const size_t neblock_quot = blocksize / type_size;
const size_t neblock_rem = blocksize % type_size;
const size_t vectorizable_elements = vectorizable_blocksize / type_size;
/* Non-optimized shuffle */
for (j = 0; j < type_size; j++) {
for (i = vectorizable_elements; i < (size_t)neblock_quot; i++) {
_dest[j*neblock_quot+i] = _src[i*type_size+j];
}
}
/* Copy any leftover bytes in the block without shuffling them. */
memcpy(_dest + (blocksize - neblock_rem), _src + (blocksize - neblock_rem), neblock_rem);
}
/**
Generic (non-hardware-accelerated) unshuffle routine.
This is the pure element-copying nested loop. It is used by the
generic unshuffle implementation and also by the vectorized unshuffle
implementations to process any remaining elements in a block which
is not a multiple of (type_size * vector_size).
*/
static void unshuffle_generic_inline(const size_t type_size,
const size_t vectorizable_blocksize, const size_t blocksize,
const uint8_t* const _src, uint8_t* const _dest)
{
size_t i, j;
/* Calculate the number of elements in the block. */
const size_t neblock_quot = blocksize / type_size;
const size_t neblock_rem = blocksize % type_size;
const size_t vectorizable_elements = vectorizable_blocksize / type_size;
/* Non-optimized unshuffle */
for (i = vectorizable_elements; i < (size_t)neblock_quot; i++) {
for (j = 0; j < type_size; j++) {
_dest[i*type_size+j] = _src[j*neblock_quot+i];
}
}
/* Copy any leftover bytes in the block without unshuffling them. */
memcpy(_dest + (blocksize - neblock_rem), _src + (blocksize - neblock_rem), neblock_rem);
}
/**
Generic (non-hardware-accelerated) shuffle routine.
*/
BLOSC_NO_EXPORT void shuffle_generic(const size_t bytesoftype, const size_t blocksize,
const uint8_t* const _src, uint8_t* const _dest);
/**
Generic (non-hardware-accelerated) unshuffle routine.
*/
BLOSC_NO_EXPORT void unshuffle_generic(const size_t bytesoftype, const size_t blocksize,
const uint8_t* const _src, uint8_t* const _dest);
#ifdef __cplusplus
}
#endif
#endif /* SHUFFLE_GENERIC_H */