TexCoords Atlas::getParentTileTexCoords(tileId id) { tileId parentId = tileId(id.z()-1, id.x()/2, id.y()/2); if (parentId.z() == 0) return TexCoords(0, glm::vec4(0.0f)); TexCoords parentCoords = getTileTexCoords(parentId); if (parentCoords.texId == 0) parentCoords = getParentTileTexCoords(parentId); if (parentCoords.texId == 0) return TexCoords(0, glm::vec4(0.0f)); glm::vec4 pCoords = parentCoords.coords; glm::vec4 childCoords(0); childCoords[0] = pCoords[0]+(pCoords[2]-pCoords[0])*0.5*(id.x()-parentId.x()*2); childCoords[1] = pCoords[1]+(pCoords[3]-pCoords[1])*0.5*(id.y()-parentId.y()*2); childCoords[2] = childCoords[0] + (pCoords[2]-pCoords[0])*0.5; childCoords[3] = childCoords[1] + (pCoords[3]-pCoords[1])*0.5; #ifdef _ATLAS_DEBUG std::cout << "[Atlas] Found parent tile=" << parentId << "for tile=" << id << std::endl; std::cout << "[Atlas] Parent coords=" << pCoords << "Child coords=" << childCoords << std::endl; #endif return TexCoords(parentCoords.texId, childCoords); }
rspfDataObject* rspfTileCache::get(const rspfDpt3d &origin, unsigned long resLevel) { rspfDataObject* result = NULL; Iterator anIterator; rspf_uint32 bucket = bucketHash(origin); anIterator = theCache[bucket].find(tileId(origin)); while(anIterator != theCache[bucket].end()) { CacheDataPtr info = (*anIterator).second; if(info) { if(info->theOrigin == origin && info->theResLevel == resLevel) { return info->theCachedTile.get(); } } ++anIterator; } return result; }
rspfDataObject* rspfTileCache::remove(const rspfDpt3d &origin, unsigned long resLevel) { Iterator anIterator; rspfDataObject *result; rspf_uint32 bucket = bucketHash(origin); anIterator = theCache[bucket].find(tileId(origin)); while(anIterator != theCache[bucket].end()) { CacheDataPtr info = (*anIterator).second; if(info) { if(info->theOrigin == origin && info->theResLevel == resLevel) { theCache[bucket].erase(anIterator); theSizeInBytes -= info->theCachedTile->getDataSizeInBytes(); result = info->theCachedTile.get(); delete info; return result; } } ++anIterator; } return NULL; }
void testGetStylesheet() { // pass zoomlevel and stylesheet directory here shared_ptr<Configuration> config; shared_ptr<RequestManager> requestManager; StylesheetManager stylesheetManager(config); stylesheetManager.startStylesheetObserving(requestManager); shared_ptr<TileIdentifier> tileId(new TileIdentifier(0, 0, 2, string("path"), TileIdentifier::Format::PNG)); shared_ptr<Stylesheet> stylesheet = stylesheetManager.getStylesheet(tileId); }
void testMatch() { shared_ptr<Stylesheet> stylesheet = Stylesheet::Load(string("test/stylesheet.mapcss"), data, 1000); shared_ptr<std::vector<NodeId> > nodeIDs(new std::vector<NodeId>()); shared_ptr<std::vector<WayId> > wayIDs(new std::vector<WayId>()); shared_ptr<std::vector<RelId> > relIDs(new std::vector<RelId>()); shared_ptr<TileIdentifier> tileId(new TileIdentifier(0, 0, 2, string("path"), TileIdentifier::Format::PNG)); RenderAttributes* attributes; stylesheet->match(nodeIDs, wayIDs, relIDs, tileId, attributes); }
rspfDataObject* rspfTileCache::insert(const rspfDpt3d &origin, rspfDataObject* data, unsigned long resLevel) { rspf_uint32 bucket = bucketHash(origin); // make sure we keep up with the current size of the // cache in bytes. This is only the count of the data // and not any overhead required by the cache. theSizeInBytes += data->getDataSizeInBytes(); theCache[bucket].insert(make_pair(tileId(origin), new CacheData(data, origin, resLevel))); return data; }
QRgb NwwMapImage::pixel( int const x, int const y ) { int const tileX = x / m_tileEdgeLengthPixel; int const tileY = y / m_tileEdgeLengthPixel; // fast check if tile is missing int const tileKey = tileId( tileX, tileY ); if ( m_tileMissing.contains( tileKey )) return m_emptyPixel; QPair<QImage, bool> potentialTile = tile( tileX, tileY ); if ( !potentialTile.second ) return m_emptyPixel; else return potentialTile.first.pixel( x % m_tileEdgeLengthPixel, m_tileEdgeLengthPixel - y % m_tileEdgeLengthPixel - 1 ); }
Atlas::Atlas(unsigned int w, unsigned int h, unsigned int tileW, unsigned int tileH, unsigned int n) { // Generate the OpenGL texture object format = GL_RGBA; width = w; height = h; tileWidth = tileW; tileHeight = tileH; nAtlases = n; for (int i = 0; i < nAtlases; i++) { GLuint texture; glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, (void *)NULL); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); textureIds.push_back(texture); } tilesInRow = w/tileWidth; tilesInCol = h/tileHeight; tilesInAtlas = tilesInRow*tilesInCol; totalTiles = tilesInAtlas * nAtlases; tilesInPositions.resize(totalTiles); usedTiles.resize(totalTiles); usedTiles.assign(totalTiles, false); for (int i = 0; i < totalTiles; i++) { tilesInPositions.push_back(tileId(0,0,0)); freePositions.push_back(i); } }
QPair<QImage, bool> NwwMapImage::tile( int const tileX, int const tileY ) { int const tileKey = tileId( tileX, tileY ); // first check cache QImage * const cachedTile = m_tileCache.object( tileKey ); if ( cachedTile ) return QPair<QImage, bool>( *cachedTile, true ); QString const filename = QString("%1/%2/%2_%3.jpg") .arg( m_baseDirectory.path() ) .arg( tileY, 4, 10, QLatin1Char('0')) .arg( tileX, 4, 10, QLatin1Char('0')); QImage tile; bool const loaded = tile.load( filename ); if ( !loaded ) { m_tileMissing.insert( tileKey ); //qDebug() << "Tile" << filename << "not found"; } else { m_tileCache.insert( tileKey, new QImage( tile ), tile.byteCount() ); //qDebug() << "Tile" << filename << "loaded and inserted in cache"; } return QPair<QImage, bool>( tile, loaded ); }
rspf_uint32 rspfTileCache::bucketHash(const rspfDpt3d &aPt) { return tileId(aPt)%theNumberOfBuckets; }
/*----------------------------------------------------------------------------*/ void SAO::onParse(StreamAccessLayer &streamAccessLayer, Decoder::State &decoder) { /* start: derived from arguments */ auto saoCoord = get<Coord>()->inUnits(); /* end: derived from arguments */ const auto rx = saoCoord.x(); const auto ry = saoCoord.y(); /* start: inferrable */ auto saoMergeLeftFlag = embed<SaoMergeLeftFlag>(*this); auto saoMergeUpFlag = embed<SaoMergeUpFlag>(*this); auto saoTypeIdxLuma = embed<SaoTypeIdxLuma>(*this); auto saoTypeIdxChroma = embed<SaoTypeIdxChroma>(*this); auto saoOffsetAbs = embed<SaoOffsetAbs>(*this); auto saoOffsetSign = embed<SaoOffsetSign>(*this); auto saoBandPosition = embed<SaoBandPosition>(*this); auto saoEoClassLuma = embed<SaoEoClassLuma>(*this); auto saoEoClassChroma = embed<SaoEoClassChroma>(*this); auto saoTypeIdx = embed<SaoTypeIdx>(*this); auto saoOffsetVal = embed<SaoOffsetVal>(*this); auto saoEoClass = embed<SaoEoClass>(*this); /* end: inferrable */ const auto picture = decoder.picture(); const auto chromaFormatIdc = picture->chromaFormatIdc; const auto slice = picture->slice(saoCoord); const auto sh = slice->header(); const auto ctu = picture->getCodingTreeUnit(saoCoord); typedef SliceSegmentHeader SSH; typedef CodingTreeUnit CTU; const auto sliceAddrInRs = slice->addr().inRs; const auto ctbAddrInRs = ctu->get<CTU::CtbAddrInRs>()->inUnits(); if(0_pel < rx) { const auto leftCtbInSliceSeg = ctbAddrInRs > sliceAddrInRs; const auto leftCtbInTile = picture->tileId(picture->toCoord(ctbAddrInRs)) == picture->tileId(picture->toCoord(ctbAddrInRs - 1_ctb)); if(leftCtbInSliceSeg && leftCtbInTile) { parse(streamAccessLayer, decoder, *saoMergeLeftFlag); } } if(0_pel < ry && !*saoMergeLeftFlag) { const auto picWidthInCtbsY = picture->widthInCtbsY; const auto upCtbInSliceSeg = (ctbAddrInRs - picWidthInCtbsY) >= sliceAddrInRs; const auto upCtbInTile = picture->tileId(picture->toCoord(ctbAddrInRs)) == picture->tileId(picture->toCoord(ctbAddrInRs - picWidthInCtbsY)); if(upCtbInSliceSeg && upCtbInTile) { parse(streamAccessLayer, decoder, *saoMergeUpFlag); } } if(*saoMergeLeftFlag || *saoMergeUpFlag) { const auto deriveAdjCoord = [saoCoord, saoMergeLeftFlag, saoMergeUpFlag]() { if(*saoMergeLeftFlag) { syntaxCheck(0_pel < saoCoord.x()); return PelCoord{saoCoord.x() - 1_pel, saoCoord.y()}; } else if(*saoMergeUpFlag) { syntaxCheck(0_pel < saoCoord.y()); return PelCoord{saoCoord.x(), saoCoord.y() - 1_pel}; } else { syntaxCheck(false); } return PelCoord{saoCoord}; }; const auto adjCoord = deriveAdjCoord(); const auto adj = picture->getCodingTreeUnit(adjCoord)->getSAO(); saoTypeIdx->merge(*adj); saoOffsetVal->merge(*adj); saoBandPosition->merge(*adj); saoEoClass->merge(*adj); } else { for(const auto cIdx : EnumRange<Plane>()) { const auto component = toComponent(cIdx); const auto isLuma = Component::Luma == component; const auto isChroma = !isLuma; if( isLuma && !(*sh->get<SSH::SliceSaoLumaFlag>()) || ChromaFormatIdc::f400 == chromaFormatIdc && isChroma || isChroma && !(*sh->get<SSH::SliceSaoChromaFlag>())) { continue; } if(Plane::Y == cIdx) { parse(streamAccessLayer, decoder, *saoTypeIdxLuma); saoTypeIdx->set(*saoTypeIdxLuma); } else if(Plane::Cb == cIdx) { parse(streamAccessLayer, decoder, *saoTypeIdxChroma); saoTypeIdx->set(*saoTypeIdxChroma); } if(SaoType::NotApplied != (*saoTypeIdx)[component]) { for(auto i = 0; i < 4; ++i) { parse(streamAccessLayer, decoder, *saoOffsetAbs, cIdx, i); } saoOffsetSign->init(cIdx, (*saoTypeIdx)[component]); if(SaoType::BandOffset == (*saoTypeIdx)[component]) { for(auto i = 0; i < 4; ++i) { if(0 != (*saoOffsetAbs)[makeTuple(cIdx, i)]) { parse(streamAccessLayer, decoder, *saoOffsetSign, cIdx, i); } } parse(streamAccessLayer, decoder, *saoBandPosition, cIdx); } else { syntaxCheck(SaoType::EdgeOffset == (*saoTypeIdx)[component]); if(Plane::Y == cIdx) { parse(streamAccessLayer, decoder, *saoEoClassLuma); } if(Plane::Cb == cIdx) { parse(streamAccessLayer, decoder, *saoEoClassChroma); } } } } typedef PpsRangeExtension PPSRE; const auto ppsre = picture->ppsre; const auto saoOffsetScaleLuma = ppsre ? ppsre->get<PPSRE::SaoOffsetScaleLuma>()->inUnits() : 0_log2; const auto saoOffsetScaleChroma = ppsre ? ppsre->get<PPSRE::SaoOffsetScaleChroma>()->inUnits() : 0_log2; saoOffsetVal->set( *saoOffsetAbs, *saoOffsetSign, saoOffsetScaleLuma, saoOffsetScaleChroma); saoEoClass->set(*saoEoClassLuma, *saoEoClassChroma); } }
ossim_uint32 ossimTileCache::bucketHash(const ossimDpt3d &aPt) { return tileId(aPt)%theNumberOfBuckets; }