static void sample_data(texgz_tex_t* src, texgz_tex_t* dst, int x, int y, int i, int j, int m, int n, double latT, double lonL, double latB, double lonR) { assert(src); assert(dst); LOGD("debug x=%i, y=%i, i=%i, j=%i, m=%i, n=%i, latT=%lf, lonL=%lf, latB=%lf, lonR=%lf", x, y, i, j, m, n, latT, lonL, latB, lonR); // make a dummy tile nedgz_tile_t* tile = nedgz_tile_new(x, y, 9); if(tile == NULL) { return; } // compute sample coords double lat; double lon; tile_coord(tile, i, j, m, n, &lat, &lon); // compute u, v float u = (float) ((lon - lonL)/(lonR - lonL)); float v = (float) ((lat - latT)/(latB - latT)); // interpolate color unsigned char r; unsigned char g; unsigned char b; interpolatec(src, u, v, &r, &g, &b); // store color unsigned char* pixels = dst->pixels; int stride = dst->stride; int bpp = texgz_tex_bpp(dst); int idx = m*stride*bpp + n*bpp; pixels[idx + 0] = r; pixels[idx + 1] = g; pixels[idx + 2] = b; nedgz_tile_delete(&tile); }
static void sample_data(texgz_tex_t* src, texgz_tex_t* dst, int x, int y, int m, int n, double latT, double lonL, double latB, double lonR) { assert(src); assert(dst); // compute sample coords double lat; double lon; float s = (float) (SUBTILE_SIZE - 1); float xx = (float) x; float yy = (float) y; float nn = (float) n/s; float mm = (float) m/s; terrain_tile2coord(xx + nn, yy + mm, 9, &lat, &lon); // compute u, v float u = (float) ((lon - lonL)/(lonR - lonL)); float v = (float) ((lat - latT)/(latB - latT)); // interpolate color unsigned char r; unsigned char g; unsigned char b; interpolatec(src, u, v, &r, &g, &b); // store color unsigned char* pixels = dst->pixels; int stride = dst->stride; int bpp = texgz_tex_bpp(dst); int idx = m*stride*bpp + n*bpp; pixels[idx + 0] = r; pixels[idx + 1] = g; pixels[idx + 2] = b; }
static void interpolatec(texgz_tex_t* tex, float u, float v, unsigned char* r, unsigned char* g, unsigned char* b) { assert(tex); LOGD("debug u=%f, v=%f", u, v); // "float indices" float pu = u*(tex->width - 1); float pv = v*(tex->height - 1); // determine indices to sample int u0 = (int) pu; int v0 = (int) pv; int u1 = u0 + 1; int v1 = v0 + 1; // double check the indices if(u0 < 0) { u0 = 0; } if(u1 >= tex->width) { u1 = tex->width - 1; } if(v0 < 0) { v0 = 0; } if(v1 >= tex->height) { v1 = tex->height - 1; } // compute interpolation coordinates float u0f = (float) u0; float v0f = (float) v0; float uf = pu - u0f; float vf = pv - v0f; // compute index int bpp = texgz_tex_bpp(tex); int stride = tex->stride; int idx00 = v0*stride*bpp + u0*bpp; int idx01 = v1*stride*bpp + u0*bpp; int idx10 = v0*stride*bpp + u1*bpp; int idx11 = v1*stride*bpp + u1*bpp; // sample interpolation values unsigned char* pixels = tex->pixels; float r00 = (float) pixels[idx00]; float r01 = (float) pixels[idx01]; float r10 = (float) pixels[idx10]; float r11 = (float) pixels[idx11]; float g00 = (float) pixels[idx00 + 1]; float g01 = (float) pixels[idx01 + 1]; float g10 = (float) pixels[idx10 + 1]; float g11 = (float) pixels[idx11 + 1]; float b00 = (float) pixels[idx00 + 2]; float b01 = (float) pixels[idx01 + 2]; float b10 = (float) pixels[idx10 + 2]; float b11 = (float) pixels[idx11 + 2]; // interpolate u float r0010 = r00 + uf*(r10 - r00); float r0111 = r01 + uf*(r11 - r01); float g0010 = g00 + uf*(g10 - g00); float g0111 = g01 + uf*(g11 - g01); float b0010 = b00 + uf*(b10 - b00); float b0111 = b01 + uf*(b11 - b01); // interpolate v *r = (unsigned char) (r0010 + vf*(r0111 - r0010) + 0.5f); *g = (unsigned char) (g0010 + vf*(g0111 - g0010) + 0.5f); *b = (unsigned char) (b0010 + vf*(b0111 - b0010) + 0.5f); }
static void naip_sampleEnd(texgz_tex_t* tex, int zoom, int x, int y) { assert(tex); // tex and node->tex are expected to have RGBA-8888 int i; int j; double lat; double lon; float xf = (float) x; float yf = (float) y; int bpp = texgz_tex_bpp(tex); unsigned char pixel00[4]; unsigned char pixel01[4]; unsigned char pixel10[4]; unsigned char pixel11[4]; float pixelf[4]; for(i = 0; i < tex->height; ++i) { int offset = bpp*i*tex->stride; for(j = 0; j < tex->width; ++j) { // compute pixel center float ii = (float) i; float jj = (float) j; float xx = xf + jj/255.0f; float yy = yf + ii/255.0f; terrain_tile2coord(xx, yy, zoom, &lat, &lon); // find/cache the naip image naip_node_t* node = naip_cache_findNode(lat, lon); if(node == NULL) { offset += bpp; continue; } // stochastic/random sampling pattern float w = (float) node->tex->width; float h = (float) node->tex->height; float ssu0 = (0.5f + 0.25*stochastic())/w; float ssu1 = (0.5f + 0.25*stochastic())/w; float ssu2 = (0.5f + 0.25*stochastic())/w; float ssu3 = (0.5f + 0.25*stochastic())/w; float ssv0 = (0.5f + 0.25*stochastic())/h; float ssv1 = (0.5f + 0.25*stochastic())/h; float ssv2 = (0.5f + 0.25*stochastic())/h; float ssv3 = (0.5f + 0.25*stochastic())/h; // sample the pixel (MSAA) double u0 = fabs(lon - node->l); double v0 = fabs(lat - node->t); double du = fabs(node->l - node->r); double dv = fabs(node->t - node->b); float u = (float) (u0/du); float v = (float) (v0/dv); texgz_tex_sample(node->tex, u - ssu0, v - ssv0, bpp, pixel00); texgz_tex_sample(node->tex, u + ssu1, v - ssv1, bpp, pixel01); texgz_tex_sample(node->tex, u - ssu2, v + ssv2, bpp, pixel10); texgz_tex_sample(node->tex, u + ssu3, v + ssv3, bpp, pixel11); // compute pixel average pixelf[0] = ((float) pixel00[0] + (float) pixel01[0] + (float) pixel10[0] + (float) pixel11[0])/4.0f; pixelf[1] = ((float) pixel00[1] + (float) pixel01[1] + (float) pixel10[1] + (float) pixel11[1])/4.0f; pixelf[2] = ((float) pixel00[2] + (float) pixel01[2] + (float) pixel10[2] + (float) pixel11[2])/4.0f; pixelf[3] = ((float) pixel00[3] + (float) pixel01[3] + (float) pixel10[3] + (float) pixel11[3])/4.0f; // set the pixel tex->pixels[offset + 0] = (unsigned char) pixelf[0]; tex->pixels[offset + 1] = (unsigned char) pixelf[1]; tex->pixels[offset + 2] = (unsigned char) pixelf[2]; tex->pixels[offset + 3] = (unsigned char) pixelf[3]; offset += bpp; } } }