1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
|
/*
* Copyright © 1999-2001 NCSA
* All rights reserved.
*
* Programmer: Robb Matzke <matzke@llnl.gov>
* Friday, August 27, 1999
*/
#include "H5private.h"
#include "H5Eprivate.h"
#include "H5MMprivate.h"
#include "H5Zprivate.h"
#ifdef H5_HAVE_FILTER_SHUFFLE
/* Interface initialization */
#define PABLO_MASK H5Z_shuffle_mask
#define INTERFACE_INIT NULL
static int interface_initialize_g = 0;
/*-------------------------------------------------------------------------
* Function: H5Z_filter_shuffle
*
* Purpose: Implement an I/O filter which "de-interlaces" a block of data
* by putting all the bytes in a byte-position for each element
* together in the block. For example, for 4-byte elements stored
* as: 012301230123, shuffling will store them as: 000111222333
* Usually, the bytes in each byte position are more related to
* each other and putting them together will increase compression.
*
* Return: Success:
*
* Failure:
*
* Programmer: Kent Yang
* Wednesday, November 13, 2002
*
* Modifications:
* Quincey Koziol, November 13, 2002
* Cleaned up code.
*
*-------------------------------------------------------------------------
*/
size_t
H5Z_filter_shuffle(unsigned flags, size_t cd_nelmts,
const unsigned cd_values[], size_t nbytes,
size_t *buf_size, void **buf)
{
void *dest = NULL; /* Buffer to deposit [un]shuffled bytes into */
unsigned char *_src; /* Alias for source buffer */
unsigned char *_dest; /* Alias for destination buffer */
unsigned bytesoftype; /* Number of bytes per element */
size_t numofelements; /* Number of elements in buffer */
size_t i,j; /* Local index variables */
size_t ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5Z_filter_shuffle, 0);
/* Check arguments */
if (cd_nelmts!=1 || cd_values[0]==0)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, 0, "invalid shuffle parameters");
/* Get the number of bytes per element from the parameter block */
bytesoftype=cd_values[0];
/* Don't do anything for 1-byte elements */
if(bytesoftype>1) {
/* Compute the number of elements in buffer */
numofelements=nbytes/bytesoftype;
/* Allocate the destination buffer */
if (NULL==(dest = H5MM_malloc(nbytes)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, 0, "memory allocation failed for shuffle buffer");
if(flags & H5Z_FLAG_REVERSE) {
/* Get the pointer to the source buffer */
_src =(unsigned char *)(*buf);
/* Input; unshuffle */
for(i=0; i<bytesoftype; i++) {
_dest=((unsigned char *)dest)+i;
for(j=0; j<numofelements; j++) {
*_dest=*_src++;
_dest+=bytesoftype;
} /* end for */
} /* end for */
} /* end if */
else {
/* Get the pointer to the destination buffer */
_dest =(unsigned char *)dest;
/* Output; shuffle */
for(i=0; i<bytesoftype; i++) {
_src=((unsigned char *)(*buf))+i;
for(j=0; j<numofelements; j++) {
*_dest++=*_src;
_src+=bytesoftype;
} /* end for */
} /* end for */
} /* end else */
/* Set the buffer information to return */
H5MM_xfree(*buf);
*buf = dest;
*buf_size=nbytes;
} /* end else */
/* Set the return value */
ret_value = nbytes;
done:
FUNC_LEAVE_NOAPI(ret_value);
}
#endif /*H5_HAVE_FILTER_SHUFFLE */
|