GRASS 8 Programmer's Manual
8.5.0(2026)-8d6ceba290
Toggle main menu visibility
Loading...
Searching...
No Matches
cmprrle.c
Go to the documentation of this file.
1
/*
2
****************************************************************************
3
* -- GRASS Development Team --
4
*
5
* MODULE: GRASS gis library
6
* FILENAME: cmprrle.c
7
* AUTHOR(S): Markus Metz
8
* PURPOSE: To provide generic RLE for compressing and
9
* decompressing data. Its primary use is in
10
* the storage and reading of GRASS rasters.
11
*
12
* ALGORITHM: Run Length Encoding
13
* DATE CREATED: Dec 18 2015
14
* COPYRIGHT: (C) 2015 by the GRASS Development Team
15
*
16
* This program is free software under the GNU General Public
17
* License (version 2 or greater). Read the file COPYING that
18
* comes with GRASS for details.
19
*
20
*****************************************************************************/
21
22
/********************************************************************
23
* int *
24
* G_rle_compress (src, srz_sz, dst, dst_sz) *
25
* int src_sz, dst_sz; *
26
* unsigned char *src, *dst; *
27
* ---------------------------------------------------------------- *
28
* This function compresses data with RLE. *
29
* It uses an all or nothing call. *
30
* If you need a continuous compression scheme, you'll have to code *
31
* your own. *
32
* *
33
* The function either returns the number of bytes of compressed *
34
* data in dst, or an error code. *
35
* *
36
* Errors include: *
37
* -1 -- Compression failed. *
38
* -2 -- dst is too small. *
39
* *
40
* ================================================================ *
41
* int *
42
* G_rle_expand (src, src_sz, dst, dst_sz) *
43
* int src_sz, dst_sz; *
44
* unsigned char *src, *dst; *
45
* ---------------------------------------------------------------- *
46
* This function decompresses data compressed with RLE. *
47
* It is equivalent to a single pass call to an external expansion *
48
* function. *
49
* If you need a continuous expansion scheme, you'll have to code *
50
* your own. *
51
* *
52
* The function returns the number of bytes expanded into 'dst' or *
53
* and error code. *
54
* *
55
* Errors include: *
56
* -1 -- Expansion failed. *
57
* *
58
********************************************************************
59
*/
60
61
#include <grass/config.h>
62
63
#include <grass/gis.h>
64
#include <grass/glocale.h>
65
66
/* no fast mode if destination is large enough to hold
67
* worst case compression */
68
int
G_rle_compress_bound
(
int
src_sz)
69
{
70
return
((src_sz >> 1) * 3 + (src_sz & 1));
71
}
72
73
int
G_rle_compress
(
unsigned
char
*src,
int
src_sz,
unsigned
char
*dst,
74
int
dst_sz)
75
{
76
int
i, nbytes;
77
unsigned
char
prev_b;
78
int
cnt;
79
80
/* Catch errors early */
81
if
(src ==
NULL
|| dst ==
NULL
)
82
return
-1;
83
84
/* Don't do anything if src is empty or smaller than 4 bytes */
85
if
(src_sz <= 3)
86
return
0;
87
88
/* modified RLE:
89
* unit is 1 byte, only sequences longer than 1 are encoded
90
* single occurrences don't have a following count
91
* multiple occurrences are twice in dst, followed by the count
92
* example:
93
* ABBCCC
94
* is encoded as
95
* ABB2CC3
96
*/
97
98
prev_b = src[0];
99
cnt = 1;
100
nbytes = 0;
101
for
(i = 1; i < src_sz; i++) {
102
if
(prev_b != src[i] || cnt == 255) {
103
/* write to dst */
104
if
(cnt == 1) {
105
if
(nbytes >= dst_sz)
106
return
-2;
107
dst[nbytes++] = prev_b;
108
}
109
else
{
110
/* cnt > 1 */
111
if
(nbytes >= dst_sz - 2)
112
return
-2;
113
dst[nbytes++] = prev_b;
114
dst[nbytes++] = prev_b;
115
dst[nbytes++] = (
unsigned
char)cnt;
116
}
117
cnt = 0;
118
}
119
prev_b = src[i];
120
cnt++;
121
}
122
/* write out the last sequence */
123
if
(cnt == 1) {
124
if
(nbytes >= dst_sz)
125
return
-2;
126
dst[nbytes++] = prev_b;
127
}
128
else
{
129
if
(nbytes >= dst_sz - 2)
130
return
-2;
131
dst[nbytes++] = prev_b;
132
dst[nbytes++] = prev_b;
133
dst[nbytes++] = (
unsigned
char)cnt;
134
}
135
136
return
nbytes;
137
}
138
139
int
G_rle_expand
(
unsigned
char
*src,
int
src_sz,
unsigned
char
*dst,
int
dst_sz)
140
{
141
int
i, j, nbytes, cnt;
142
unsigned
char
prev_b;
143
144
/* Catch errors early */
145
if
(src ==
NULL
|| dst ==
NULL
)
146
return
-1;
147
148
/* Don't do anything if src is empty */
149
if
(src_sz <= 0)
150
return
0;
151
152
/* RLE expand */
153
prev_b = src[0];
154
cnt = 1;
155
nbytes = 0;
156
i = 1;
157
while
(i < src_sz) {
158
/* single occurrences don't have a following count
159
* multiple occurrences are twice in src, followed by the count */
160
if
(cnt == 2) {
161
if
(i >= src_sz)
162
return
-1;
163
cnt = src[i];
164
if
(nbytes + cnt > dst_sz)
165
return
-1;
166
for
(j = 0; j < cnt; j++) {
167
dst[nbytes++] = prev_b;
168
}
169
cnt = 0;
170
i++;
171
if
(i >= src_sz)
172
return
nbytes;
173
}
174
if
(cnt == 1) {
175
if
(prev_b != src[i]) {
176
if
(nbytes + cnt > dst_sz)
177
return
-1;
178
dst[nbytes++] = prev_b;
179
cnt = 0;
180
}
181
}
182
prev_b = src[i];
183
cnt++;
184
i++;
185
}
186
if
(nbytes >= dst_sz)
187
return
-1;
188
if
(cnt == 1)
189
dst[nbytes++] = prev_b;
190
191
return
nbytes;
192
}
193
194
/* vim: set softtabstop=4 shiftwidth=4 expandtab: */
NULL
#define NULL
Definition
ccmath.h:32
G_rle_compress_bound
int G_rle_compress_bound(int src_sz)
Definition
cmprrle.c:68
G_rle_compress
int G_rle_compress(unsigned char *src, int src_sz, unsigned char *dst, int dst_sz)
Definition
cmprrle.c:73
G_rle_expand
int G_rle_expand(unsigned char *src, int src_sz, unsigned char *dst, int dst_sz)
Definition
cmprrle.c:139
gis
cmprrle.c
Generated on
for GRASS 8 Programmer's Manual by
1.17.0