forked from dankelley/oce
-
Notifications
You must be signed in to change notification settings - Fork 0
/
landsat.cpp
157 lines (147 loc) · 4.28 KB
/
landsat.cpp
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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
/* vim: set expandtab shiftwidth=2 softtabstop=2 tw=70: */
#include <Rcpp.h>
using namespace Rcpp;
// Cross-reference work:
// 1. update ../src/registerDynamicSymbol.c with an item for this
// 2. main code should use the autogenerated wrapper in ../R/RcppExports.R
//
// NB. breaking work up into two functions may slow things down but
// it makes it simpler to check.
// #define DEBUG // uncomment this for debugging info
// [[Rcpp::export]]
RawMatrix do_landsat_transpose_flip(RawMatrix m)
{
#ifdef DEBUG
Rprintf("do_landsat_transpose_flip() start\n");
#endif
int nrow = m.nrow();
int ncol = m.ncol();
#ifdef DEBUG
Rprintf("nrow=%d ncol=%d\n", nrow, ncol);
#endif
RawMatrix res(ncol, nrow); // this is the *transpose* dimension, so ncol then nrow
int nrow_res = ncol;
int ncol_res = nrow;
// Transpose
#ifdef DEBUG
Rprintf("start transpose ...\n");
#endif
for (int i = 0; i < nrow; i++) {
for (int j = 0; j < ncol; j++) {
res(j, i) = m(i, j);
}
}
#ifdef DEBUG
Rprintf("... transpose done\n");
#endif
// Flip in second dimension
// ncol_res_half is to avoid undoing the flip by repeating it.
#ifdef DEBUG
Rprintf("start flip ...\n");
#endif
int ncol_res_half = (int)floor(ncol_res / 2.0);
for (int i = 0; i < nrow_res; i++) {
for (int j = 0; j < ncol_res_half; j++) {
unsigned char tmp = res(i, j);
res(i, j) = res(i, ncol_res-j-1);
res(i, ncol_res-j-1) = tmp;
}
}
#ifdef DEBUG
Rprintf("... end flip\n");
#endif
return(res);
}
// [[Rcpp::export]]
List do_landsat_numeric_to_bytes(NumericMatrix m, IntegerVector bits)
{
#ifdef DEBUG
Rprintf("do_landsat_numeric_to_bytes() start\n");
#endif
int nrow = m.nrow();
int ncol = m.ncol();
int two_byte = bits[0] > 8;
// The most-significant matrix is just 1x1 for 8-bit data
RawMatrix lsb(nrow, ncol);
RawMatrix msb(two_byte?nrow:1, two_byte?ncol:1);
// Check endianness
unsigned int x = 1;
char *c = (char*) &x;
int little_endian = (int)*c;
#ifdef DEBUG
Rprintf("little_endian: %d\n", little_endian);
#endif
// fill up arrays
// No need to index by i and j here; this will speed up
int n = nrow * ncol;
if (two_byte) {
if (little_endian) {
unsigned int mij_int;
unsigned char ms, ls;
#ifdef DEBUG
Rprintf("little-endian two-byte nrow=%d ncol=%d\n", nrow, ncol);
#endif
for (int i = 0; i < n; i++) {
mij_int = (unsigned int)(65535*m[i]);
ms = (mij_int & 0xFF00) >> 8;
ls = mij_int & 0x00FF;
//#ifdef DEBUG
// Rprintf("i %d, m: %f -> %d -> msb 0x%02x lsb 0x%02x (little endian two-byte)\n", i, m[i], mij_int, ms, ls);
//#endif
lsb[i] = ls;
msb[i] = ms;
}
} else {
#ifdef DEBUG
Rprintf("big-endian two-byte nrow=%d ncol=%d\n", nrow, ncol);
#endif
// big endian below
for (int i = 0; i < n; i++) {
double mij = m[i];
unsigned int mij_int = (unsigned int)(65535*mij);
unsigned char ls = (mij_int & 0xFF00) >> 8;
unsigned char ms = mij_int & 0x00FF;
#ifdef DEBUG
Rprintf("i %d, m: %f -> %d -> msb 0x%02x lsb 0x%02x (big endian two-byte)\n", i, mij, mij_int, ms, ls);
#endif
lsb[i] = ls;
msb[i] = ms;
}
}
} else {
// !two_byte: msb is scalar 0; just fill up lsb
if (little_endian) {
#ifdef DEBUG
Rprintf("little-endian one-byte nrow=%d ncol=%d\n", nrow, ncol);
#endif
for (int i = 0; i < n; i++) {
double mij = m[i];
unsigned int mij_int = (unsigned int)(255*mij);
unsigned char ls = mij_int; // & 0xFF00;
//#ifdef DEBUG
// Rprintf("i=%d %f -> %d -> lsb 0x%02x (little endian one-byte)\n", i, mij, mij_int, ls);
//#endif
lsb[i] = ls;
}
} else {
// big endian
#ifdef DEBUG
Rprintf("big-endian one-byte nrow=%d ncol=%d\n", nrow, ncol);
#endif
unsigned int mij_int;
unsigned char ls;
for (int i = 0; i < n; i++) {
mij_int = (unsigned int)(255*m[i]);
ls = mij_int; // & 0x00FF;
//#ifdef DEBUG
// Rprintf("i=%d %f -> %d -> lsb 0x%02x (big endian one-byte)\n", i, m[i], mij_int, ls);
//#endif
lsb[i] = ls;
}
}
}
#ifdef DEBUG
Rprintf("do_landsat_numeric_to_bytes() done\n");
#endif
return(List::create(Named("lsb")=lsb, Named("msb")=msb));
}