void GetLevel0Map( glTextureDescriptor *ptd, const wxRect &rect, wxString &chart_path ) { // Load level 0 uncompressed data wxRect ncrect(rect); ptd->map_array[0] = 0; ChartBase *pChart = ChartData->OpenChartFromDB( chart_path, FULL_INIT ); if( !pChart ) { ptd->map_array[0] = (unsigned char *) calloc( ncrect.width * ncrect.height * 4, 1 ); return; } // Prime the pump with the "zero" level bits, ie. 1x native chart bits ChartBaseBSB *pBSBChart = dynamic_cast<ChartBaseBSB*>( pChart ); if( pBSBChart ) { unsigned char *t_buf = (unsigned char *) malloc( ncrect.width * ncrect.height * 4 ); pBSBChart->GetChartBits( ncrect, t_buf, 1 ); // and cache them here ptd->map_array[0] = t_buf; } else { ptd->map_array[0] = (unsigned char *) calloc( ncrect.width * ncrect.height * 4, 1 ); return; } }
bool JobTicket::DoJob(const wxRect &rect) { unsigned char *bit_array[10]; for(int i=0 ; i < 10 ; i++) bit_array[i] = 0; wxRect ncrect(rect); bit_array[0] = level0_bits; level0_bits = NULL; if(!bit_array[0]) { // Grab a copy of the level0 chart bits // we could alternately subsample grabbing leveln chart bits // directly here to speed things up... ChartBase *pchart; int index; if(ChartData){ index = ChartData->FinddbIndex( m_ChartPath ); pchart = ChartData->OpenChartFromDBAndLock(index, FULL_INIT ); if(pchart && ChartData->IsChartLocked( index )){ ChartBaseBSB *pBSBChart = dynamic_cast<ChartBaseBSB*>( pchart ); if( pBSBChart ) { bit_array[0] = (unsigned char *) malloc( ncrect.width * ncrect.height * 4 ); pBSBChart->GetChartBits( ncrect, bit_array[0], 1 ); } ChartData->UnLockCacheChart(index); } else bit_array[0] = NULL; } } //OK, got the bits? int ssize, dim; if(!bit_array[0] ) return false; // Fill in the rest of the private uncompressed array dim = g_GLOptions.m_iTextureDimension; dim /= 2; for( int i = 1 ; i < g_mipmap_max_level+1 ; i++ ){ size_t nmalloc = wxMax(dim * dim * 3, 4*4*3); bit_array[i] = (unsigned char *) malloc( nmalloc ); MipMap_24( 2*dim, 2*dim, bit_array[i - 1], bit_array[i] ); dim /= 2; } int texture_level = 0; for( int level = level_min_request; level < g_mipmap_max_level+1 ; level++ ){ int dim = TextureDim(level); int size = TextureTileSize(level, true); unsigned char *tex_data = (unsigned char*)malloc(size); if(g_raster_format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT) { // color range fit is worse quality but twice as fast int flags = squish::kDxt1 | squish::kColourRangeFit; if( g_GLOptions.m_bTextureCompressionCaching) { /* use slower cluster fit since we are building the cache for * better quality, this takes roughly 25% longer and uses about * 10% more disk space (result doesn't compress as well with lz4) */ flags = squish::kDxt1 | squish::kColourClusterFit; } OCPNStopWatch sww; squish::CompressImageRGBpow2_Flatten_Throttle_Abort( bit_array[level], dim, dim, tex_data, flags, true, b_throttle ? throttle_func : 0, &sww, b_abort ); } else if(g_raster_format == GL_ETC1_RGB8_OES) CompressDataETC(bit_array[level], dim, size, tex_data, b_abort); else if(g_raster_format == GL_COMPRESSED_RGB_FXT1_3DFX) { if(!CompressUsingGPU(bit_array[level], dim, size, tex_data, texture_level, binplace)) { b_abort = true; break; } if(binplace) g_tex_mem_used += size; texture_level++; } comp_bits_array[level] = tex_data; if(b_abort){ for( int i = 0; i < g_mipmap_max_level+1; i++ ){ free( bit_array[i] ); bit_array[i] = 0; } return false; } } // All done with the uncompressed data in the thread for( int i = 0; i < g_mipmap_max_level+1; i++ ) { free( bit_array[i] ); bit_array[i] = 0; } if(b_throttle) wxThread::Sleep(1); if(b_abort) return false; if(bpost_zip_compress) { int max_compressed_size = LZ4_COMPRESSBOUND(g_tile_size); for(int level = level_min_request; level < g_mipmap_max_level+1 ; level++){ if(b_abort) return false; unsigned char *compressed_data = (unsigned char *)malloc(max_compressed_size); int csize = TextureTileSize(level, true); char *src = (char *)comp_bits_array[level]; int compressed_size = LZ4_compressHC2( src, (char *)compressed_data, csize, 4); // shrink buffer to actual size. // This will greatly reduce ram usage, ratio usually 10:1 // there might be a more efficient way than realloc... compressed_data = (unsigned char*)realloc(compressed_data, compressed_size); compcomp_bits_array[level] = compressed_data; compcomp_size_array[level] = compressed_size; } } return true; }