ZObject3dScan ZDvidInfo::getBlockIndex(const ZObject3dScan &obj) const { ZIntPoint gridSize = m_endBlockIndex - m_startBlockIndex + 1; size_t area = ((size_t) gridSize.getX()) * gridSize.getY(); size_t blockNumber = area * gridSize.getZ(); std::vector<bool> isAdded(blockNumber, false); //std::set<ZIntPoint> blockSet; //ZIntPointArray blockArray; ZObject3dScan blockObj; for (size_t i = 0; i < obj.getStripeNumber(); ++i) { #ifdef _DEBUG_2 if (i % 10000 == 0) { std::cout << i << "/" << obj.getStripeNumber() << std::endl; } #endif const ZObject3dStripe &stripe = obj.getStripe(i); int y = stripe.getY(); int z = stripe.getZ(); if (y > 0 && z > 0 && y < m_startCoordinates[1] + m_stackSize[1] && z < m_startCoordinates[2] + m_stackSize[2]) { for (int j = 0; j < stripe.getSegmentNumber(); ++j) { int x0 = stripe.getSegmentStart(j); int x1 = stripe.getSegmentEnd(j); if (x0 < 0) { x0 = 0; } else if (x0 >= m_startCoordinates[0] + m_stackSize[0]) { x0 = m_startCoordinates[0] + m_stackSize[0] - 1; } if (x1 < 0) { x1 = 0; } else if (x1 >= m_startCoordinates[0] + m_stackSize[0]) { x1 = m_startCoordinates[0] + m_stackSize[0] - 1; } ZIntPoint block1 = getBlockIndex(x0, y, z); size_t blockIndex1 = area * block1.getZ() + gridSize.getY() * block1.getY() + block1.getX(); ZIntPoint block2 = getBlockIndex(x1, y, z); size_t blockIndex2 = area * block2.getZ() + gridSize.getY() * block2.getY() + block2.getX(); if (!isAdded[blockIndex1] || !isAdded[blockIndex2]) { blockObj.addSegment( block1.getZ(), block1.getY(), block1.getX(), block2.getX(), false); isAdded[blockIndex1] = true; isAdded[blockIndex2] = true; } } } } //blockArray.append(blockSet.begin(), blockSet.end()); blockObj.canonize(); return blockObj; }
ZObject3dScan ZDvidInfo::getBlockIndex(const ZIntCuboid &box) const { ZIntPoint startIndex = getBlockIndex(box.getFirstCorner()); ZIntPoint endIndex = getBlockIndex(box.getLastCorner()); return ZObject3dFactory::MakeObject3dScan(ZIntCuboid(startIndex, endIndex)); }
MapAoiBlock* MapAoi::getBlock(int x, int y) { MapAoiBlock* ret = NULL; int row = getBlockIndex(x); int column = getBlockIndex(y); if(row >= 0 && row < m_side_block_num && column >= 0 && column < m_side_block_num) { ret = m_blocks+row*m_side_block_num+column; } return ret; }
/* 在文件系统中加载文件,文件大小写入size所指变量,返回bool值表示是否成功 */ bool loadFile(const char *path, uint32_t partitionFirstSector, uint32_t *size) { printString(" "); firstSector = partitionFirstSector; loadSector(firstSector + 2, superBlockBuffer); blockSize = (uint32_t) (1024 << superBlock->logBlockSize); sectorsPerBlock = blockSize / SECTOR_SIZE_512; if (superBlock->magic != EXT2_MAGIC_NUM) { printLine("incorrect ext2 magic number"); return false; } if (superBlock->revLevel < EXT2_DYNAMIC_REV) { printLine("reversion of this ext2 filesystem is too old"); return false; } if (blockSize > 0x10000) { printLine("block size is too large"); return false; } uint32_t targetInode = EXT2_INODE_ROOT; for (const char *nameEnd = path; *nameEnd != '\0';) { for (path = nameEnd; *path == '/'; ++path); for (nameEnd = path; *nameEnd != '/' && *nameEnd != '\0'; ++nameEnd); if (nameEnd == path) { break; } targetInode = findChild(targetInode, path, nameEnd - path); if (targetInode == EXT2_INODE_NULL) { printLine("can't find such file"); return false; } }; Ext2Inode inode = loadInode(targetInode); if ((inode.mode & EXT2_MODE_FT_MASK) != EXT2_MODE_FT_REG_FILE) { printLine("not a regular file"); return false; } else { printString("file found, size: "); printInt(inode.size); printString(" bytes ("); printStorageSize(inode.size); printLine(")"); } uint32_t blkCnt = inode.size / blockSize + (inode.size % blockSize != 0); for (uint32_t blockOffset = 0; blockOffset < blkCnt; ++blockOffset) { uint32_t block = getBlockIndex(&inode, blockOffset); if (!readFileSectorsToBuffer(lbaOfBlock(block), sectorsPerBlock)) { return false; } } *size = inode.size; return true; }
// TODO YukigassenChunkRoom should probably pass a pointer to an object that can store the triangles and filaments instead of passing pointer to itself. void YukigassenVoxelMap::setupInternalRenderingDataLocal(const YukigassenChunkRoom *ybr, YukigassenChunk *yukigassenChunk) { assert(ybr==getParentObj()); /*void YukigassenVoxelMap::setupInternalRenderingDataLocal(YukigassenChunk *yukigassenChunk) { const YukigassenChunkRoom *ybr=dynamic_cast<const YukigassenChunkRoom *>(getParentObj());*/ if (ybr!=NULL) { const float bsx2 = 0.5f * ybr->blockSizeX(); const float bsy2 = 0.5f * ybr->blockSizeY(); const float bsz2 = 0.5f * ybr->blockSizeZ(); const int subXo=ybr->translateToVoxelMapIndexX(geographicIndex)*mapSizeInBlocks.x; const int subYo=ybr->translateToVoxelMapIndexY(geographicIndex)*mapSizeInBlocks.y; const int subZo=ybr->translateToVoxelMapIndexZ(geographicIndex)*mapSizeInBlocks.z; //addLineBox(0.0f, 0.0f, 0.0f, rsx2, rsy2, rsz2); //printf("setupInternalRenderingDataLocal: %d %d %d\n", subXo, subYo, subZo); for(size_t lx=0;lx<mapSizeInBlocks.x;lx++) { for(size_t ly=0;ly<mapSizeInBlocks.y;ly++) { for(size_t lz=0;lz<mapSizeInBlocks.z;lz++) { const long long blockIndex = getBlockIndex(lx,ly,lz); const int b = getVoxel(blockIndex); if (!YukigassenChunk::getBlockInvisible(b)) { int rx=subXo+lx; int ry=subYo+ly; int rz=subZo+lz; // TODO Would be much faster to not do this via parent unless needed. int neighborMask = ybr->getNeighborMaskXp(rx,ry,rz) | ybr->getNeighborMaskYp(rx,ry,rz) | ybr->getNeighborMaskZp(rx,ry,rz) | ybr->getNeighborMaskXn(rx,ry,rz) | ybr->getNeighborMaskYn(rx,ry,rz) | ybr->getNeighborMaskZn(rx,ry,rz); //int neighborMask=0x1f; float xc = ybr->translateBlockToCoordinatesX(rx); float yc = ybr->translateBlockToCoordinatesY(ry); float zc = ybr->translateBlockToCoordinatesZ(rz); //printf("setupInternalRenderingDataLocal: %f %f %f %03x %d\n", xc, yc, zc, neighborMask, b); //if ((bsx2==bsy2) && (bsy2==bsz2)) {}; if (neighborMask!=0x3F) { yukigassenChunk->addTriangleBox(xc, yc, zc, bsx2, bsy2, bsz2, neighborMask, b); } } } } } } }
const TilePtr& Map::getTile(const Position& pos) { if(!pos.isMapPosition()) return m_nulltile; auto it = m_tileBlocks[pos.z].find(getBlockIndex(pos)); if(it != m_tileBlocks[pos.z].end()) return it->second.get(pos); return m_nulltile; }
ZObject3dScan ZDvidInfo::getBlockIndex(const ZIntCuboidArray &boxArray) const { ZObject3dScan obj; for (ZIntCuboidArray::const_iterator iter = boxArray.begin(); iter != boxArray.end(); ++iter) { const ZIntCuboid &box = *iter; obj.unify(getBlockIndex(box)); } return obj; }
void ThreadedDyscoColumn<DataType>::putValues(casacore::uInt rowNr, const casacore::Array<DataType>* dataPtr) { if(!areOffsetsInitialized()) { // If the manager did not initialize its offsets yet, then it is determined // from the first "time block" (a block with the same time, field and spw) that // is written into the measurement set. // // This only happens when a new measurement // set was created; if an existing measurement set is opened with at least one block, // then the offsets will be read from the headers. // // A consequence of this is that the first blocks in a new measurement set are required to // be written consecutively. double time = (*_timeCol)(rowNr); int fieldId = (*_fieldCol)(rowNr); int dataDescId = (*_dataDescIdCol)(rowNr); if(_timeBlockBuffer->Empty()) { // This is the first row written _currentBlock = 0; _lastWrittenTime = time; _lastWrittenField = fieldId; _lastWrittenDataDescId = dataDescId; } else if(time != _lastWrittenTime || fieldId != _lastWrittenField || dataDescId != _lastWrittenDataDescId) { initializeRowsPerBlock(rowNr, _timeBlockBuffer->MaxAntennaIndex() + 1); } } const int ant1 = (*_ant1Col)(rowNr), ant2 = (*_ant2Col)(rowNr); if(areOffsetsInitialized()) { const size_t blockIndex = getBlockIndex(rowNr), blockRow = getRowWithinBlock(rowNr); // Is this the first row of a new block? if(blockIndex != _currentBlock) { if(_isCurrentBlockChanged) storeBlock(); // Load new block loadBlock(blockIndex); } _timeBlockBuffer->SetData(blockRow, ant1, ant2, dataPtr->data()); } else { _timeBlockBuffer->SetData(rowNr, ant1, ant2, dataPtr->data()); } _isCurrentBlockChanged = true; }
const TilePtr& Map::getOrCreateTile(const Position& pos) { if(!pos.isMapPosition()) return m_nulltile; if(pos.x < m_tilesRect.left()) m_tilesRect.setLeft(pos.x); if(pos.y < m_tilesRect.top()) m_tilesRect.setTop(pos.y); if(pos.x > m_tilesRect.right()) m_tilesRect.setRight(pos.x); if(pos.y > m_tilesRect.bottom()) m_tilesRect.setBottom(pos.y); TileBlock& block = m_tileBlocks[pos.z][getBlockIndex(pos)]; return block.getOrCreate(pos); }
double getBlockHardness(int height) { const CBlockIndex* blockindex = getBlockIndex(height); int nShift = (blockindex->nBits >> 24) & 0xff; double dDiff = (double)0x0000ffff / (double)(blockindex->nBits & 0x00ffffff); while (nShift < 29) { dDiff *= 256.0; nShift++; } while (nShift > 29) { dDiff /= 256.0; nShift--; } return dDiff; }
void ThreadedDyscoColumn<DataType>::getValues(casacore::uInt rowNr, casacore::Array<DataType>* dataPtr) { if(!areOffsetsInitialized()) { // Trying to read before first block was written -- return zero // TODO if a few rows were written of the first block, those are // incorrectly returned. This is a rare case but can be fixed. for(typename casacore::Array<DataType>::contiter i=dataPtr->cbegin(); i!=dataPtr->cend(); ++i) *i = DataType(); } else { size_t blockIndex = getBlockIndex(rowNr); if(blockIndex >= nBlocksInFile()) { // Trying to read a row that was not stored yet -- return zero for(typename casacore::Array<DataType>::contiter i=dataPtr->cbegin(); i!=dataPtr->cend(); ++i) *i = DataType(); } else { mutex::scoped_lock lock(_mutex); // Wait until the block to be read is not in the write cache typename cache_t::const_iterator cacheItemPtr = _cache.find(blockIndex); while(cacheItemPtr != _cache.end()) { _cacheChangedCondition.wait(lock); cacheItemPtr = _cache.find(blockIndex); } lock.unlock(); if(_currentBlock != blockIndex) { if(_isCurrentBlockChanged) storeBlock(); loadBlock(blockIndex); } // The time block encoder is now initialized and contains the unpacked block. _timeBlockBuffer->GetData(getRowWithinBlock(rowNr), dataPtr->data()); } } }
void Map::cleanTile(const Position& pos) { if(!pos.isMapPosition()) return; auto it = m_tileBlocks[pos.z].find(getBlockIndex(pos)); if(it != m_tileBlocks[pos.z].end()) { TileBlock& block = it->second; if(const TilePtr& tile = block.get(pos)) { tile->clean(); if(tile->canErase()) block.remove(pos); notificateTileUpdate(pos); } } for(auto it = m_staticTexts.begin();it != m_staticTexts.end();) { const StaticTextPtr& staticText = *it; if(staticText->getPosition() == pos && staticText->getMessageMode() == Otc::MessageNone) it = m_staticTexts.erase(it); else ++it; } }
BOOL WINAPI SFileOpenFileEx(HANDLE hArchive, char * fileName, int something, HANDLE * hFile) { TMPQArchive * ha = (TMPQArchive *)hArchive; TMPQFile * hf; TMPQBlock * block; // File block DWORD blockIndex; // Found table index if(hFile != NULL) *hFile = NULL; if(hArchive == NULL || fileName == NULL || *fileName == 0 || hFile == NULL) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } // If opened file is simple PLAIN file if(ha->header->id != ID_MPQ) { // Allocate file handle if((hf = new TMPQFile) == NULL) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); return FALSE; } // Initialize file handle memset(hf, 0, sizeof(TMPQFile)); hf->hFile = ha->hFile; hf->hArchive = ha; *hFile = hf; } // Get block index from file name blockIndex = getBlockIndex(ha, fileName); // If index was not found, or is greater than number of files, exit. if(blockIndex == -1 || blockIndex > ha->header->nFiles) { SetLastError(ERROR_FILE_NOT_FOUND); return FALSE; } // Get block and test it block = ha->block + blockIndex; if(block->fsize == 0 || (block->flags & 0x80000000) == 0) { SetLastError(ERROR_BAD_FORMAT); return FALSE; } // Skip ':' in the file name while(strchr(fileName, '\\') != NULL) fileName = strchr(fileName, '\\') + 1; // Allocate file handle (ESI = hFile); // EBP - block if((hf = new TMPQFile) == NULL) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); return FALSE; } // Initialize file handle memset(hf, 0, sizeof(TMPQFile)); hf->hFile = INVALID_HANDLE_VALUE; hf->hArchive = ha; hf->block = block; hf->nBlocks = (hf->block->fsize + ha->blockSize - 1) / ha->blockSize; hf->seed1 = decryptFileSeed(fileName, stormBuffer); if(hf->block->flags & MPQ_FILE_FIXSEED) hf->seed1 = (hf->seed1 + hf->block->filePos - ha->mpqPos) ^ hf->block->fsize; // Allocate buffers for decompression. if(hf->block->flags & MPQ_FILE_COMPRESSED) { // Buffer for decompressed data. Always must be 0x1000 bytes length, // because this is length of decompressed block required by PKWARE data compression library. // hf->buffer = new BYTE[0x1000]; // Allocate buffer for block positions. At the begin of file are stored // DWORDs holding positions of each block relative from begin of file in the archive if((hf->blockPos = new DWORD[hf->nBlocks + 1]) == NULL) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); return FALSE; } } *hFile = hf; return TRUE; }
static uint32_t findChild( uint32_t dirInode, const char *childName, uint32_t nameLen) { Ext2Inode inode = loadInode(dirInode); if ((inode.mode & EXT2_MODE_FT_MASK) != EXT2_MODE_FT_DIR) { return EXT2_INODE_NULL; } /* 目录项一定占用整数个块,blkCnt */ uint32_t blkCnt = inode.size / blockSize + (inode.size % blockSize != 0); /* 一个目录项不可能跨块,但可能跨扇区,用第二个缓冲区作为副缓冲区 */ uint8_t buffers[2][SECTOR_SIZE_512]; uint32_t bufferedSector2 = 0; /* 当前的目录项和下一个目录项的指针 */ Ext2DirEntry *curEntry; Ext2DirEntry *nextEntry; /* 遍历目录文件的每一个块 */ for (uint32_t blockOffset = 0; blockOffset < blkCnt; ++blockOffset) { uint32_t block = getBlockIndex(&inode, blockOffset); if (block == INVALID_DATA_BLOCK) { return EXT2_INODE_NULL; } nextEntry = (Ext2DirEntry *) &buffers[0]; /* 遍历目录文件的每一个扇区 */ for (uint32_t sectorOffset = 0; sectorOffset < sectorsPerBlock;) { /* 副缓冲区本用作存储长文件名,但若其中有对应扇区,复制之,避免IO */ uint32_t sector = lbaOfBlock(block) + sectorOffset; if (sector == bufferedSector2) { for (uint32_t i = 0; i < SECTOR_SIZE_512; ++i) { buffers[0][i] = buffers[1][i]; } } else { loadSector(sector, buffers[0]); } /* 遍历目录项,不确定退出时机 */ for (;;) { /* 空目录项或者文件名不相等就直接跳过 */ if ((curEntry = nextEntry)->inode != EXT2_INODE_NULL && curEntry->nameLen == nameLen) { /* 如果文件名跨扇区,就要用副缓冲区延伸保存了 */ if (((uintptr_t) curEntry + offsetof(Ext2DirEntry, name) + curEntry->nameLen) >= (uintptr_t) &buffers[0] + SECTOR_SIZE_512) { bufferedSector2 = sector + 1; loadSector(bufferedSector2, buffers[1]); } /* 文件名一致就返回正确inode */ for (uint32_t i = 0; i < nameLen; ++i) { if (curEntry->name[i] != childName[i]) { break; } if (i == nameLen - 1) { return curEntry->inode; } } } /* next是nextEntry的uintptr_t形式表达 */ uintptr_t next = (uintptr_t) curEntry + curEntry->recLen; /* 下一个目录项是否超过扇区大小 */ if (next >= (uintptr_t) &buffers[0] + SECTOR_SIZE_512) { /* 是则要增加扇区偏移并且回滚nextEntry值,并结束当前扇区 */ uintptr_t offset = next - (uintptr_t) &buffers[0]; sectorOffset += offset / SECTOR_SIZE_512; next = (uintptr_t) &buffers[0] + offset % SECTOR_SIZE_512; nextEntry = (Ext2DirEntry *) next; break; } else { /* 否则继续在本扇区寻找 */ nextEntry = (Ext2DirEntry *) next; } } } } return EXT2_INODE_NULL; }
YukigassenVoxelMap::YukigassenVoxelMap() : MirrorContainer(), geographicIndex(-1), mapSizeInBlocks(0,0,0), voxelMap(NULL) #ifdef NEIGBOUR_MAP neighbourMap(NULL), #endif { } YukigassenVoxelMap::~YukigassenVoxelMap() { free(voxelMap); #ifdef NEIGBOUR_MAP free(neighbourMap); #endif } void YukigassenVoxelMap::readSelf(WordReader *wr) { MirrorContainer::readSelf(wr); free(voxelMap); // Free old data area if any #ifdef NEIGBOUR_MAP free(neighbourMap); // Free old data area if any #endif geographicIndex = wr->readLong(); mapSizeInBlocks.readSelf(wr); size_t voxelMapSize = mapSizeInBlocks.x * mapSizeInBlocks.y * mapSizeInBlocks.z; voxelMap = (char *)malloc(voxelMapSize); // free is done in destructor free(voxelMap); assert(voxelMap!=NULL); #ifdef NEIGBOUR_MAP neighbourMap = (char *)malloc(voxelMapSize); assert(neighbourMap!=NULL); #endif for(size_t x=0;x<mapSizeInBlocks.x;x++) { for(size_t y=0;y<mapSizeInBlocks.y;y++) { for(size_t z=0;z<mapSizeInBlocks.z;z++) { const int b=wr->readInt(); const int index = getBlockIndex(x,y,z); voxelMap[index]=b; } } } #ifdef NEIGBOUR_MAP // Calculate neighbourMask for(size_t x=0;x<mapSizeInBlocks.x;x++) { for(size_t y=0;y<mapSizeInBlocks.y;y++) { for(size_t z=0;z<mapSizeInBlocks.z;z++) { const int index = getBlockIndex(x,y,z); neighbourMap[index] = getNeighborMaskXp(x,y,z) | getNeighborMaskYp(x,y,z) | getNeighborMaskZp(x,y,z) | getNeighborMaskXn(x,y,z) | getNeighborMaskYn(x,y,z) | getNeighborMaskZn(x,y,z); } } } #endif }
void Chunk::initBlock(vec3ui8 intraChunkCoords, uint8 type) { blocks[getBlockIndex(intraChunkCoords)] = type; }
ZIntPoint ZDvidInfo::getBlockIndex(const ZIntPoint &blockIndex) const { return getBlockIndex(blockIndex.getX(), blockIndex.getY(), blockIndex.getZ()); }
void Chunk::makePassThroughs() { if (numAirBlocks > SIZE - WIDTH * WIDTH) { passThroughs = 0x7FFF; return; } else if (numAirBlocks == 0) { passThroughs = 0x0000; return; } passThroughs = 0; bool visited[SIZE]; for (uint i = 0; i < SIZE; i++) { visited[i] = false; } size_t index = 0; uint foundAirBlocks = 0; for (uint8 z = 0; z < WIDTH; z++) { for (uint8 y = 0; y < WIDTH; y++) { for (uint8 x = 0; x < WIDTH; x++) { visited[index] = true; if (blocks[index] != 0) { index++; continue; } vec3ui8 fringe[SIZE]; fringe[0] = vec3ui8(x, y, z); int fringeSize = 1; int borderSet = 0; while (fringeSize > 0) { foundAirBlocks++; vec3ui8 icc = fringe[--fringeSize]; for (int d = 0; d < 6; d++) { if (icc[DIR_DIMS[d]] == (1 - d / 3) * (WIDTH - 1)) borderSet |= (1 << d); else { vec3ui8 nIcc = icc + DIRS[d].cast<uint8>(); size_t nIndex = getBlockIndex(nIcc); if (blocks[nIndex] == 0 && !visited[nIndex]) { visited[nIndex] = true; fringe[fringeSize++] = nIcc; } } } } int shift = 0; for (int d1 = 0; d1 < 5; d1++) { if (borderSet & (1 << d1)) { for (int d2 = d1 + 1; d2 < 6; d2++) { if (borderSet & (1 << d2)) passThroughs |= (1 << shift); shift++; } } else shift += 5 - d1; } if (foundAirBlocks >= numAirBlocks) return; index++; } } } }
uint8 Chunk::getBlock(vec3ui8 icc) const { return blocks[getBlockIndex(icc)]; }