static void naip_node_delete(naip_node_t** _self) { assert(_self); naip_node_t* self = *_self; if(self) { texgz_tex_delete(&self->tex); free(self); *_self = NULL; } }
int main(int argc, char** argv) { if(argc != 1) { LOGE("usage: %s", argv[0]); return EXIT_FAILURE; } // create temporary working image texgz_tex_t* dst = texgz_tex_new(SUBTILE_SIZE, SUBTILE_SIZE, SUBTILE_SIZE, SUBTILE_SIZE, TEXGZ_UNSIGNED_BYTE, TEXGZ_RGB, NULL); if(dst == NULL) { return EXIT_FAILURE; } int month; char fname[256]; const char* base = "png/world.topo.bathy.2004"; const char* size = "3x21600x21600"; for(month = 1; month <= 12; ++month) { snprintf(fname, 256, "%s%02i.%s.A1.png", base, month, size); sample_sector(dst, month, 0, 0, 90.0, -180.0, 0.0, -90.0, fname); snprintf(fname, 256, "%s%02i.%s.B1.png", base, month, size); sample_sector(dst, month, 0, 1, 90.0, -90.0, 0.0, 0.0, fname); snprintf(fname, 256, "%s%02i.%s.C1.png", base, month, size); sample_sector(dst, month, 0, 2, 90.0, 0.0, 0.0, 90.0, fname); snprintf(fname, 256, "%s%02i.%s.D1.png", base, month, size); sample_sector(dst, month, 0, 3, 90.0, 90.0, 0.0, 180.0, fname); snprintf(fname, 256, "%s%02i.%s.A2.png", base, month, size); sample_sector(dst, month, 1, 0, 0.0, -180.0, -90.0, -90.0, fname); snprintf(fname, 256, "%s%02i.%s.B2.png", base, month, size); sample_sector(dst, month, 1, 1, 0.0, -90.0, -90.0, 0.0, fname); snprintf(fname, 256, "%s%02i.%s.C2.png", base, month, size); sample_sector(dst, month, 1, 2, 0.0, 0.0, -90.0, 90.0, fname); snprintf(fname, 256, "%s%02i.%s.D2.png", base, month, size); sample_sector(dst, month, 1, 3, 0.0, 90.0, -90.0, 180.0, fname); } texgz_tex_delete(&dst); return EXIT_SUCCESS; }
void lzs_renderer_delete(lzs_renderer_t** _self) { assert(_self); lzs_renderer_t* self = *_self; if(self) { LOGD("debug"); a3d_texstring_delete(&self->string_fps); a3d_texstring_delete(&self->string_phone); a3d_texstring_delete(&self->string_sphero); a3d_texfont_delete(&self->font); texgz_tex_delete(&self->buffer_sy); texgz_tex_delete(&self->buffer_sx); texgz_tex_delete(&self->buffer_gray); texgz_tex_delete(&self->buffer_color); glBindTexture(GL_TEXTURE_EXTERNAL_OES, 0); glDeleteTextures(1, &self->texid); free(self); *_self = NULL; } }
static void sample_subtile(texgz_tex_t* src, pak_file_t* pak, int x, int y, int i, int j, double latT, double lonL, double latB, double lonR) { assert(src); assert(pak); LOGD("debug x=%i, y=%i, i=%i, j=%i, latT=%lf, lonL=%lf, latB=%lf, lonR=%lf", x, y, i, j, latT, lonL, latB, lonR); // create dst texgz_tex_t* dst = texgz_tex_new(SUBTILE_SIZE, SUBTILE_SIZE, SUBTILE_SIZE, SUBTILE_SIZE, TEXGZ_UNSIGNED_BYTE, TEXGZ_RGB, NULL); if(dst == NULL) { return; } int m; int n; for(m = 0; m < SUBTILE_SIZE; ++m) { for(n = 0; n < SUBTILE_SIZE; ++n) { sample_data(src, dst, x, y, i, j, m, n, latT, lonL, latB, lonR); } } // convert dst to 565 texgz_tex_convert(dst, TEXGZ_UNSIGNED_SHORT_5_6_5, TEXGZ_RGB); char key[256]; snprintf(key, 256, "%i_%i", j, i); pak_file_writek(pak, key); texgz_tex_exportf(dst, pak->f); texgz_tex_delete(&dst); }
static void sample_sector(texgz_tex_t* dst, int month, int r, int c, double latT, double lonL, double latB, double lonR, const char* fname) { assert(dst); assert(fname); LOGI("%s", fname); texgz_tex_t* src = texgz_png_import(fname); if(src == NULL) { return; } // convert src to 888 (should be already) texgz_tex_convert(src, TEXGZ_UNSIGNED_BYTE, TEXGZ_RGB); // 2^9 gives 512 tiles at zoom=9 int t = 512; int x; int y; int xmin = (t/4)*c; int xmax = (t/4)*(c + 1); int ymin = (t/2)*r; int ymax = (t/2)*(r + 1); for(y = ymin; y < ymax; ++y) { for(x = xmin; x < xmax; ++x) { sample_tile(src, dst, month, x, y, latT, lonL, latB, lonR); } } texgz_tex_delete(&src); }
static void sample_sector(int month, int r, int c, double latT, double lonL, double latB, double lonR, const char* fname) { assert(fname); LOGD("debug month=%i, r=%i, c=%i, latT=%lf, lonL=%ls, latB=%lf, lonR=%lf, fname=%s", month, r, c, latT, lonL, latB, lonR, fname); LOGI("%s", fname); texgz_tex_t* src = texgz_png_import(fname); if(src == NULL) { return; } // convert src to 888 (should be already) texgz_tex_convert(src, TEXGZ_UNSIGNED_BYTE, TEXGZ_RGB); // 2^9*256/2048 gives 64 tiles at zoom=9 int t = 64; int x; int y; int xmin = (t/4)*c; int xmax = (t/4)*(c + 1); int ymin = (t/2)*r; int ymax = (t/2)*(r + 1); for(y = ymin; y < ymax; ++y) { for(x = xmin; x < xmax; ++x) { sample_tile(src, month, x, y, latT, lonL, latB, lonR); } } texgz_tex_delete(&src); }
static int sample_subtile(nedgz_tile_t* tile, int i, int j, pak_file_t* pak) { assert(tile); LOGD("debug i=%i, j=%i", i, j); texgz_tex_t* tex = texgz_tex_new(SUBTILE_SIZE, SUBTILE_SIZE, SUBTILE_SIZE, SUBTILE_SIZE, TEXGZ_SHORT, TEXGZ_LUMINANCE, NULL); if(tex == NULL) { return 0; } int m; int n; for(m = 0; m < SUBTILE_SIZE; ++m) { for(n = 0; n < SUBTILE_SIZE; ++n) { double lat; double lon; tile_coord(tile, i, j, m, n, &lat, &lon); // flt_cc most likely place to find sample // At edges of range a subtile may not be // fully covered by flt_xx short height; if((flt_cc && flt_tile_sample(flt_cc, lat, lon, &height)) || (flt_tc && flt_tile_sample(flt_tc, lat, lon, &height)) || (flt_bc && flt_tile_sample(flt_bc, lat, lon, &height)) || (flt_cl && flt_tile_sample(flt_cl, lat, lon, &height)) || (flt_cr && flt_tile_sample(flt_cr, lat, lon, &height)) || (flt_tl && flt_tile_sample(flt_tl, lat, lon, &height)) || (flt_bl && flt_tile_sample(flt_bl, lat, lon, &height)) || (flt_tr && flt_tile_sample(flt_tr, lat, lon, &height)) || (flt_br && flt_tile_sample(flt_br, lat, lon, &height))) { short* pixels = (short*) tex->pixels; pixels[m*SUBTILE_SIZE + n] = height; } else { short* pixels = (short*) tex->pixels; pixels[m*SUBTILE_SIZE + n] = NEDGZ_NODATA; } } } // j=dx, i=dy char fname[256]; snprintf(fname, 256, "%i_%i", j, i); pak_file_writek(pak, fname); texgz_tex_exportf(tex, pak->f); texgz_tex_delete(&tex); return 1; }
int main(int argc, char** argv) { unsigned char dx = 0; unsigned char dy = 0; const char* arg_format = NULL; const char* arg_src = NULL; const char* arg_dst = NULL; if(argc == 6) { dx = (unsigned char) strtoul(argv[2], (char**) NULL, 10); dy = (unsigned char) strtoul(argv[3], (char**) NULL, 10); arg_format = argv[1]; arg_src = argv[4]; arg_dst = argv[5]; } else if(argc == 4) { arg_format = argv[1]; arg_src = argv[2]; arg_dst = argv[3]; if(check_ext(arg_src, "mgm")) { usage(argv[0]); return EXIT_FAILURE; } } else { usage(argv[0]); return EXIT_FAILURE; } // parse format int type; int format; if(strcmp(arg_format, "RGBA-8888") == 0) { type = TEXGZ_UNSIGNED_BYTE; format = TEXGZ_RGBA; } else if(strcmp(arg_format, "BGRA-8888") == 0) { type = TEXGZ_UNSIGNED_BYTE; format = TEXGZ_BGRA; } else if(strcmp(arg_format, "RGB-565") == 0) { type = TEXGZ_UNSIGNED_SHORT_5_6_5; format = TEXGZ_RGB; } else if(strcmp(arg_format, "RGBA-4444") == 0) { type = TEXGZ_UNSIGNED_SHORT_4_4_4_4; format = TEXGZ_RGBA; } else if(strcmp(arg_format, "RGB-888") == 0) { type = TEXGZ_UNSIGNED_BYTE; format = TEXGZ_RGB; } else if(strcmp(arg_format, "RGBA-5551") == 0) { type = TEXGZ_UNSIGNED_SHORT_5_5_5_1; format = TEXGZ_RGBA; } else if(strcmp(arg_format, "LUMINANCE") == 0) { type = TEXGZ_UNSIGNED_BYTE; format = TEXGZ_LUMINANCE; } else if(strcmp(arg_format, "LUMINANCE-F") == 0) { type = TEXGZ_FLOAT; format = TEXGZ_LUMINANCE; } else { LOGE("invalid format=%s", arg_format); return EXIT_FAILURE; } // import src texgz_tex_t* tex = NULL; if(check_ext(arg_src, "texgz")) { tex = texgz_tex_import(arg_src); } else if(check_ext(arg_src, "jpg")) { tex = texgz_jpeg_import(arg_src); } else if(check_ext(arg_src, "png")) { tex = texgz_png_import(arg_src); } else if(check_ext(arg_src, "mgm")) { tex = texgz_mgm_import(arg_src, dx, dy); } else { LOGE("invalid src=%s", arg_src); return EXIT_FAILURE; } if(tex == NULL) { return EXIT_FAILURE; } // convert to format if(texgz_tex_convert(tex, type, format) == 0) { goto fail_convert; } // export dst int ret = 0; if(check_ext(arg_dst, "texgz")) { ret = texgz_tex_export(tex, arg_dst); } else if(check_ext(arg_dst, "jpg")) { ret = texgz_jpeg_export(tex, arg_dst); } else if(check_ext(arg_dst, "png")) { ret = texgz_png_export(tex, arg_dst); } else { LOGE("invalid dst=%s", arg_dst); goto fail_dst; } if(ret == 0) { goto fail_export; } texgz_tex_delete(&tex); // success return EXIT_SUCCESS; // failure fail_export: fail_dst: fail_convert: texgz_tex_delete(&tex); return EXIT_FAILURE; }
int main(int argc, char** argv) { // osm.list // zoom x y if(argc != 2) { LOGE("usage: %s [osm.list]", argv[0]); return EXIT_FAILURE; } // create directories if necessary char dname[256]; snprintf(dname, 256, "%s", "osm"); if(mkdir(dname, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) == -1) { if(errno == EEXIST) { // already exists } else { LOGE("mkdir %s failed", dname); return EXIT_FAILURE; } } // open the list FILE* f = fopen(argv[1], "r"); if(f == NULL) { LOGE("failed to open %s", argv[1]); return EXIT_FAILURE; } // iteratively pak osm images char* line = NULL; size_t n = 0; int index = 0; while(getline(&line, &n, f) > 0) { int x; int y; int zoom; if(sscanf(line, "%i %i %i", &zoom, &x, &y) != 3) { LOGE("invalid line=%s", line); continue; } LOGI("%i: zoom=%i, x=%i, y=%i", index++, zoom, x, y); // create directories if necessary char dname[256]; snprintf(dname, 256, "osm/%i", zoom); if(mkdir(dname, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) == -1) { if(errno == EEXIST) { // already exists } else { LOGE("mkdir %s failed", dname); continue; } } char fname[256]; snprintf(fname, 256, "osm/%i/%i_%i.pak", zoom, x, y); pak_file_t* pak = pak_file_open(fname, PAK_FLAG_WRITE); if(pak == NULL) { continue; } int i; int j; for(i = 0; i < 8; ++i) { for(j = 0; j < 8; ++j) { int xj = 8*x + j; int yi = 8*y + i; snprintf(fname, 256, "localhost/osm/%i/%i/%i.png", zoom, xj, yi); texgz_tex_t* tex = texgz_png_import(fname); if(tex == NULL) { continue; } if(texgz_tex_convert(tex, TEXGZ_UNSIGNED_SHORT_4_4_4_4, TEXGZ_RGBA) == 0) { texgz_tex_delete(&tex); continue; } // j=dx, i=dy snprintf(fname, 256, "%i_%i", j, i); pak_file_writek(pak, fname); texgz_tex_exportf(tex, pak->f); texgz_tex_delete(&tex); } } pak_file_close(&pak); } free(line); return EXIT_SUCCESS; }
lzs_renderer_t* lzs_renderer_new(const char* font) { assert(s); LOGD("debug"); lzs_renderer_t* self = (lzs_renderer_t*) malloc(sizeof(lzs_renderer_t)); if(self == NULL) { LOGE("malloc failed"); return NULL; } self->sphero_x = 400.0f; self->sphero_y = 240.0f; self->sphero_X = 0.0f; self->sphero_Y = 0.0f; self->sphero_speed = 0.0f; self->sphero_heading = 0.0f; self->sphero_heading_offset = 0.0f; self->sphero_goal = 0.0f; self->phone_heading = 0.0f; self->phone_slope = 0.0f; self->phone_height = 5.0f; self->t0 = a3d_utime(); self->frames = 0; // allocate the buffer(s) GLint bsize = 2 * ((int) RADIUS_BALL); GLint format = TEXGZ_BGRA; GLint type = TEXGZ_UNSIGNED_BYTE; self->buffer_color = texgz_tex_new(bsize, bsize, bsize, bsize, type, format, NULL); if(self->buffer_color == NULL) { goto fail_color; } format = TEXGZ_LUMINANCE; type = TEXGZ_FLOAT; self->buffer_gray = texgz_tex_new(bsize, bsize, bsize, bsize, type, format, NULL); if(self->buffer_gray == NULL) { goto fail_gray; } self->buffer_sx = texgz_tex_new(bsize, bsize, bsize, bsize, type, format, NULL); if(self->buffer_sx == NULL) { goto fail_sx; } self->buffer_sy = texgz_tex_new(bsize, bsize, bsize, bsize, type, format, NULL); if(self->buffer_sy == NULL) { goto fail_sy; } // create the font self->font = a3d_texfont_new(font); if(self->font == NULL) { goto fail_font; } // create the string(s) self->string_sphero = a3d_texstring_new(self->font, 64, 24, A3D_TEXSTRING_TOP_CENTER, 1.0f, 1.0f, 0.235f, 1.0f); if(self->string_sphero == NULL) { goto fail_string_sphero; } self->string_phone = a3d_texstring_new(self->font, 64, 24, A3D_TEXSTRING_TOP_CENTER, 1.0f, 1.0f, 0.235f, 1.0f); if(self->string_phone == NULL) { goto fail_string_phone; } self->string_fps = a3d_texstring_new(self->font, 16, 24, A3D_TEXSTRING_BOTTOM_RIGHT, 1.0f, 1.0f, 0.235f, 1.0f); if(self->string_fps == NULL) { goto fail_string_fps; } glGenTextures(1, &self->texid); glEnableClientState(GL_VERTEX_ARRAY); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glDisable(GL_DEPTH_TEST); // success return self; // failure fail_string_fps: a3d_texstring_delete(&self->string_phone); fail_string_phone: a3d_texstring_delete(&self->string_sphero); fail_string_sphero: a3d_texfont_delete(&self->font); fail_font: texgz_tex_delete(&self->buffer_sy); fail_sy: texgz_tex_delete(&self->buffer_sx); fail_sx: texgz_tex_delete(&self->buffer_gray); fail_gray: texgz_tex_delete(&self->buffer_color); fail_color: free(self); return NULL; }
static void naip_sampleStart(void) { texgz_tex_t* tex = naip_sampleNode(0, 0, 0); texgz_tex_delete(&tex); }
void naip_cache(naip_node_t* node) { assert(node); // update LRU if already cached if(node->tex) { if(node == glru) { return; } naip_node_t* prev = node->prev; naip_node_t* next = node->next; if(prev) { prev->next = next; } if(next) { next->prev = prev; } node->prev = NULL; node->next = glru; glru->prev = node; glru = node; return; } LOGI("import %s", node->fname); node->tex = texgz_jp2_import(node->fname); if(node->tex == NULL) { LOGE("fatal error importing %s", node->fname); exit(EXIT_FAILURE); } // force the jp2 to RGBA if(texgz_tex_convert(node->tex, TEXGZ_UNSIGNED_BYTE, TEXGZ_RGBA) == 0) { LOGE("fatal error converting %s", node->fname); texgz_tex_delete(&node->tex); exit(EXIT_FAILURE); } // insert node into cache node->prev = NULL; node->next = glru; if(glru) { glru->prev = node; } glru = node; // evict excess nodes int count = 0; while(node) { ++count; if(count > NAIP_CACHE_SIZE) { naip_node_t* prev = node->prev; naip_node_t* next = node->next; if(prev) { prev->next = next; } if(next) { next->prev = prev; } texgz_tex_delete(&node->tex); node->prev = NULL; node->next = NULL; node = next; } else { node = node->next; } } }
static texgz_tex_t* naip_sampleNode(int zoom, int x, int y) { // restart the saved node if it exists char sname[256]; if((zoom == 12) || (zoom == 3)) { snprintf(sname, 256, "naipsave/%i/%i/%i.texz", zoom, x, y); sname[255] = '\0'; if(access(sname, F_OK) == 0) { // assume this LOD already completed texgz_tex_t* down = texgz_tex_importz(sname); if(down) { LOGI("restart %s", sname); return down; } } } // terrain tiles only exist up to zoom 15 // and zoom > 15 is covered by zoom 15 short min; short max; int flags = TERRAIN_NEXT_ALL; if(zoom < 15) { if(terrain_tile_header(".", x, y, zoom, &min, &max, &flags) == 0) { return NULL; } } // create a working texture texgz_tex_t* tex = texgz_tex_new(256, 256, 256, 256, TEXGZ_UNSIGNED_BYTE, TEXGZ_RGBA, NULL); if(tex == NULL) { return NULL; } // prefetch images used by z17 (naip_sampleEnd) // cache should easily hold all images needed for z12-z17 // z12=256, z13=512, z14=1024 // z15=2048, z16=4096, z17=8192 if(zoom == 12) { naip_cache_prefetch(zoom, x, y); } // sample the next/end LOD // naip data roughly corresponds to zoom 17 if(zoom == 17) { if(naip_cache_isCached(zoom, x, y)) { naip_sampleEnd(tex, zoom, x, y); } } else { texgz_tex_t* tmp; if(flags & TERRAIN_NEXT_TL) { tmp = naip_sampleNode(zoom + 1, 2*x, 2*y); if(tmp) { texgz_tex_blit(tmp, tex, 128, 128, 0, 0, 0, 0); texgz_tex_delete(&tmp); } } if(flags & TERRAIN_NEXT_BL) { tmp = naip_sampleNode(zoom + 1, 2*x, 2*y + 1); if(tmp) { texgz_tex_blit(tmp, tex, 128, 128, 0, 0, 0, 128); texgz_tex_delete(&tmp); } } if(flags & TERRAIN_NEXT_TR) { tmp = naip_sampleNode(zoom + 1, 2*x + 1, 2*y); if(tmp) { texgz_tex_blit(tmp, tex, 128, 128, 0, 0, 128, 0); texgz_tex_delete(&tmp); } } if(flags & TERRAIN_NEXT_BR) { tmp = naip_sampleNode(zoom + 1, 2*x + 1, 2*y + 1); if(tmp) { texgz_tex_blit(tmp, tex, 128, 128, 0, 0, 128, 128); texgz_tex_delete(&tmp); } } } // export the JPEG texture char fname[256]; snprintf(fname, 256, "naipjpg/%i/%i/%i.jpg", zoom, x, y); fname[255] = '\0'; { char pname[256]; snprintf(pname, 256, "naipjpg/%i/%i/%i.jpg.part", zoom, x, y); pname[255] = '\0'; if(naip_mkdir(fname) == 0) { goto fail_export; } if(texgz_jpeg_export(tex, pname) == 0) { goto fail_export; } if(rename(pname, fname) != 0) { LOGE("rename failed %s", fname); unlink(pname); goto fail_export; } LOGI("export %s", fname); } // compute the downscaled texture for the next LOD texgz_tex_t* down = texgz_tex_downscale(tex); if(down == NULL) { goto fail_down; } // save the output for restart if((zoom == 12) || (zoom == 3)) { char pname[256]; snprintf(pname, 256, "naipsave/%i/%i/%i.texz.part", zoom, x, y); pname[255] = '\0'; if(naip_mkdir(sname) == 0) { goto fail_save; } if(texgz_tex_exportz(down, pname) == 0) { goto fail_save; } if(rename(pname, sname) != 0) { LOGE("rename failed %s", sname); unlink(pname); goto fail_save; } LOGI("export %s", sname); } texgz_tex_delete(&tex); // success return down; // failure fail_save: texgz_tex_delete(&down); fail_down: unlink(fname); fail_export: texgz_tex_delete(&tex); return NULL; }
a3d_spriteTex_t* a3d_spriteTex_new(const char* fname, const char* resource) { assert(fname); assert(resource); LOGD("debug fname=%s, resource=%s", fname, resource); a3d_spriteTex_t* self = (a3d_spriteTex_t*) malloc(sizeof(a3d_spriteTex_t)); if(self == NULL) { LOGE("malloc failed"); return NULL; } pak_file_t* pak = NULL; texgz_tex_t* tex = NULL; if(fname[0] == '$') { pak = pak_file_open(resource, PAK_FLAG_READ); if(pak) { const char* key = &(fname[1]); int size = pak_file_seek(pak, key); if(size > 0) { tex = texgz_tex_importf(pak->f, size); } else { LOGE("invalid fname=%s", fname); } pak_file_close(&pak); } } else { tex = texgz_tex_import(fname); } if(tex == NULL) { goto fail_tex; } // load tex glGenTextures(1, &self->id_tex); glBindTexture(GL_TEXTURE_2D, self->id_tex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexImage2D(GL_TEXTURE_2D, 0, tex->format, tex->stride, tex->vstride, 0, tex->format, tex->type, tex->pixels); // no longer needed texgz_tex_delete(&tex); strncpy(self->fname, fname, 256); self->fname[255] = '\0'; self->ref_count = 0; // success return self; // failure fail_tex: free(self); return NULL; }