/* Table name and column names are stored all together in a single * memory chunk. During configuration, when names are added, it * grows by powers of 2, so that (1) at most half of the memory * in the chunk is wasted and (2) the number of reallocs is kept under * `o(log2(n))`, where `n` is the number of columns. * * After the last column name is added, a final realloc is performed * by `sdb_setcolumn()` to reclaim wasted memory. */ static int new_conf_string( sdb_table_t *tbl, const char *str) { if( ! str) str=""; int length = strlen( str) + 1; int old_block_size = nextpwr2( tbl->conf_string_idx); int new_block_size = nextpwr2( tbl->conf_string_idx + length); int old_used_size; if( old_block_size != new_block_size) { char *d = BS_MEM_REALLOC( tbl->conf_strings, old_block_size, new_block_size); if( ! d) return SDB_EMEM; tbl->conf_strings = d; } old_used_size = tbl->conf_string_idx; memcpy( tbl->conf_strings + old_used_size, str, length); tbl->conf_string_idx += length; return old_used_size; }
static int addcolumn( sdb_table_t *tbl, const char *label) { sdb_column_t *c = tbl->columns + tbl->conf_col; // TODO: if it's a persisted table, check consistency instead of setting // up configuration? if( tbl->state != SDB_ST_UNCONFIGURED) return SDB_EBADSTATE; c->label_offset = new_conf_string( tbl, label); if( c->label_offset<0) { return SDB_EMEM; } else if( ++tbl->conf_col == tbl->ncolumns) { tbl->state = SDB_ST_READING; // Trim unnecessary space at the end of sting cfg; tbl->conf_strings = BS_MEM_REALLOC( tbl->conf_strings, nextpwr2( tbl->conf_string_idx), tbl->conf_string_idx); // read existing cells if table is a file #ifdef SDB_FILE_SUPPORT if( tbl->storage_kind == SDB_SK_FILE) { sdb_restore_file_cells( tbl); } #endif } int r = sdb_setcolumn( tbl, label, SDB_SM_SMALLEST, 0.0); return r; }
int Texture::from_surface(SDL_Surface* surface) { // Free any previous content if(loaded) unload(); // Local variables for extracting properties about the image GLuint n_colours = 0; GLenum format = (GLenum) NULL; // Make sure the image length and width are powers of 2 area = iRect(0, 0, ISPWR2(surface->w) ? surface->w : nextpwr2(surface->w), ISPWR2(surface->h) ? surface->h : nextpwr2(surface->h)); if(area.w != surface->w || area.h != surface->h) { // enlarge the surface if needed SDL_Surface* previous_surface = surface; surface = SDL_CreateRGBSurface(0, area.w, area.h, 32, /* NB - Hexadecimal parameters are: Rmask, Gmask, Bmask and Amask */ 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000); // past contents of previous (small) surface onto new (larger) surface SDL_BlitSurface(previous_surface, 0, surface, 0); } //get number of channels in the SDL surface n_colours = surface->format->BytesPerPixel; switch(n_colours) { case 1: format = GL_LUMINANCE; break; case 2: format = GL_LUMINANCE_ALPHA; break; case 3: format = GL_RGB; break; case 4: format = GL_RGBA; break; default: log(LOG_ERROR, "Load texture failed : Image must be LUMINANCE, RGB or RGBA"); return EXIT_FAILURE; break; } // Request an OpenGL unassigned GLuint to identify this texture glGenTextures(1, &handle); // Bind the texture object to the current block glBindTexture(GL_TEXTURE_2D, handle); // Set the texture’s properties glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); // Finally: convert the image to a texture glTexImage2D(GL_TEXTURE_2D, 0, n_colours, area.w, area.h, 0, format, GL_UNSIGNED_BYTE, surface->pixels); // Unbind the texture glBindTexture(GL_TEXTURE_2D, 0); // The return result reports the success of the operation loaded = true; return EXIT_SUCCESS; }