コード例 #1
0
ファイル: SurfaceSet.cpp プロジェクト: 2xG/OpenXcom
/**
 * Loads the contents of an X-Com set of PCK/TAB image files
 * into the surface. The PCK file contains an RLE compressed
 * image, while the TAB file contains the offsets to each
 * frame in the image.
 * @param pck Filename of the PCK image.
 * @param tab Filename of the TAB offsets.
 * @sa http://www.ufopaedia.org/index.php?title=Image_Formats#PCK
 */
void SurfaceSet::loadPck(const std::string &pck, const std::string &tab)
{
	int nframes = 0;

	// Load TAB and get image offsets
	std::ifstream offsetFile (tab.c_str(), std::ios::in | std::ios::binary);
	if (!offsetFile)
	{
		nframes = 1;
		Surface *surface = new Surface(_width, _height);
		_frames[0] = surface;
	}
	else
	{
		Uint16 off;
		while (offsetFile.read((char*)&off, sizeof(off)))
		{
			off = SDL_SwapLE16(off);
			Surface *surface = new Surface(_width, _height);
			_frames[nframes] = surface;
			nframes++;
		}
	}

	// Load PCX and put pixels in surfaces
	std::ifstream imgFile (pck.c_str(), std::ios::in | std::ios::binary);
	if (!imgFile)
	{
		throw Exception(pck + " not found");
	}

	Uint8 value;

	for (int frame = 0; frame < nframes; frame++)
	{
		int x = 0, y = 0;

		// Lock the surface
		_frames[frame]->lock();

		imgFile.read((char*)&value, 1);
		for (int i = 0; i < value; ++i)
		{
			for (int j = 0; j < _width; ++j)
			{
				_frames[frame]->setPixelIterative(&x, &y, 0);
			}
		}

		while (imgFile.read((char*)&value, 1) && value != 255)
		{
			if (value == 254)
			{
				imgFile.read((char*)&value, 1);
				for (int i = 0; i < value; ++i)
				{
					_frames[frame]->setPixelIterative(&x, &y, 0);
				}
			}
			else
			{
				_frames[frame]->setPixelIterative(&x, &y, value);
			}
		}

		// Unlock the surface
		_frames[frame]->unlock();
	}

	imgFile.close();
	offsetFile.close();
}
コード例 #2
0
ScanRLEArrayIterator::ScanRLEArrayIterator(const RLEArray * const source, AttributeID attId, string path, size_t maxChunkNo) :
    currChunk(NULL), logger(log4cxx::Logger::getLogger("scidb.query.ops.ScanRQArrayIterator")), _attId(attId), _dirPath(path), _chunkNo(0),
            _maxChunkNo(maxChunkNo), _desc(&source->getArrayDesc()), _currPos(_desc->getDimensions().size(), 0)
{
    if (_desc->getAttributes()[attId].getFlags() & AttributeDesc::IS_NULLABLE)
    {
        throw SYSTEM_EXCEPTION(SCIDB_SE_INTERNAL, SCIDB_LE_NOT_IMPLEMENTED) << "nullable attributes";
    }
    if (_desc->getAttributes()[attId].getSize() == 0)
    {
        throw SYSTEM_EXCEPTION(SCIDB_SE_INTERNAL, SCIDB_LE_NOT_IMPLEMENTED) << "variable size attributes";
    }

    // set up the file offsets and chunk sizes
    uint8_t attrBytes, chunkBytes, offsetBytes;
    stringstream chunkFileName, offsetFileName;
    chunkId lhs0, lhs1;
    chunkFileInfo rhs0, rhs1;

    chunkFileName << path << "/chunks";
    offsetFileName << path << "/offsets";

    ifstream offsetFile(offsetFileName.str().c_str(), ios_base::binary | ios_base::in | ios_base::ate);
    _chunkFile.open(chunkFileName.str().c_str(), ios_base::binary | ios_base::in | ios_base::ate);

    size_t offsetFileSize = offsetFile.tellg();
    size_t chunkFileSize = _chunkFile.tellg();

    offsetFile.seekg(0, ios_base::beg);
    offsetFile.read((char *) &attrBytes, 1);
    offsetFile.read((char *) &chunkBytes, 1);
    offsetBytes = sizeof(size_t);

    size_t offsetChunks = offsetFileSize / (attrBytes + chunkBytes + offsetBytes);

    // init them all
    rhs0.first = rhs0.second = rhs1.first = rhs1.second = lhs0.first = lhs0.second = lhs1.first = lhs1.second = 0;

    // read starter chunk
    offsetFile.read((char *) &lhs0.first, attrBytes);
    offsetFile.read((char *) &lhs0.second, chunkBytes);
    offsetFile.read((char *) &rhs0.first, offsetBytes);

    // the chunk size is wrong because it will be off by one
    for (size_t i = 1; i < offsetChunks; ++i)
    {
        // read in tuple 1
        offsetFile.read((char *) &lhs1.first, attrBytes);
        offsetFile.read((char *) &lhs1.second, chunkBytes);
        offsetFile.read((char *) &rhs1.first, offsetBytes);

        // calculate chunk offset of predecessor
        rhs0.second = rhs1.first - rhs0.first;

        // commit it
        _chunkFileData[lhs0] = rhs0;

        // roll over to the next one
        lhs0 = lhs1;
        rhs0 = rhs1;
    }

    // output the last one
    rhs0.second = chunkFileSize - rhs0.first;
    _chunkFileData[lhs0] = rhs0;

    reset();
}
コード例 #3
0
LidarProcessOctree::LidarProcessOctree(const char* lidarFileName,size_t sCacheSize)
	:indexFile(getLidarPartFileName(lidarFileName,"Index").c_str()),
	 pointsFile(getLidarPartFileName(lidarFileName,"Points").c_str()),
	 offset(OffsetVector::zero),
	 numSubdivideCalls(0),numLoadedNodes(0),
	 lruHead(0),lruTail(0)
	{
	indexFile.setEndianness(Misc::LittleEndian);
	pointsFile.setEndianness(Misc::LittleEndian);
	
	/* Read the octree file header: */
	LidarOctreeFileHeader ofh(indexFile);
	
	/* Initialize the root node's domain: */
	root.domain=ofh.domain;
	
	/* Initialize the tree structure: */
	maxNumPointsPerNode=ofh.maxNumPointsPerNode;
	
	/* Calculate the memory and GPU cache sizes: */
	size_t memNodeSize=sizeof(Node)+size_t(maxNumPointsPerNode)*sizeof(LidarPoint);
	cacheSize=(unsigned int)(sCacheSize/memNodeSize);
	if(cacheSize==0U)
		Misc::throwStdErr("LidarProcessOctree::LidarProcessOctree: Specified memory cache size too small");
	std::cout<<"Cache size: "<<cacheSize<<" memory nodes"<<std::endl;
	
	/* Read the root node's structure: */
	LidarOctreeFileNode rootfn;
	rootfn.read(indexFile);
	root.childrenOffset=rootfn.childrenOffset;
	root.numPoints=rootfn.numPoints;
	root.dataOffset=rootfn.dataOffset;
	root.detailSize=rootfn.detailSize;
	
	/* Get the total number of nodes by dividing the index file's size by the size of one octree node: */
	numNodes=size_t((indexFile.getSize()-LidarOctreeFileHeader::getFileSize())/LidarFile::Offset(LidarOctreeFileNode::getFileSize()));
	
	/* Read the point file's header: */
	LidarDataFileHeader dfh(pointsFile);
	pointsRecordSize=LidarFile::Offset(dfh.recordSize);
	
	if(root.numPoints>0)
		{
		/* Load the root node's points: */
		root.points=new LidarPoint[maxNumPointsPerNode]; // Always allocate maximum to prevent memory fragmentation
		pointsFile.setReadPosAbs(LidarDataFileHeader::getFileSize()+pointsRecordSize*root.dataOffset);
		pointsFile.read(root.points,root.numPoints);
		}
	
	++numLoadedNodes;
	
	/* Try loading an offset file: */
	try
		{
		IO::FilePtr offsetFile(IO::openFile(getLidarPartFileName(lidarFileName,"Offset").c_str()));
		offsetFile->setEndianness(Misc::LittleEndian);
		
		/* Read the original offset vector: */
		offsetFile->read<OffsetVector::Scalar>(offset.getComponents(),3);
		
		/* Invert the offset transformation: */
		offset=-offset;
		}
	catch(IO::File::OpenError err)
		{
		/* Ignore the error */
		}
	
	/* Initialize the node cache: */
	numCachedNodes=1U;
	}
コード例 #4
0
int main(int argc,char* argv[])
	{
	/* Set default values for all parameters: */
	unsigned int memoryCacheSize=512;
	unsigned int tempOctreeMaxNumPointsPerNode=4096;
	std::string tempOctreeFileNameTemplate="/tmp/LidarPreprocessorTempOctree";
	unsigned int maxNumPointsPerNode=4096;
	int numThreads=1;
	std::string tempPointFileNameTemplate="/tmp/LidarPreprocessorTempPoints";
	
	try
		{
		/* Open LidarViewer's configuration file: */
		Misc::ConfigurationFile configFile(LIDARVIEWER_CONFIGFILENAME);
		Misc::ConfigurationFileSection cfg=configFile.getSection("/LidarPreprocessor");
		
		/* Override program settings from configuration file: */
		memoryCacheSize=cfg.retrieveValue<unsigned int>("./memoryCacheSize",memoryCacheSize);
		tempOctreeMaxNumPointsPerNode=cfg.retrieveValue<unsigned int>("./tempOctreeMaxNumPointsPerNode",tempOctreeMaxNumPointsPerNode);
		tempOctreeFileNameTemplate=cfg.retrieveValue<std::string>("./tempOctreeFileNameTemplate",tempOctreeFileNameTemplate);
		maxNumPointsPerNode=cfg.retrieveValue<unsigned int>("./maxNumPointsPerNode",maxNumPointsPerNode);
		numThreads=cfg.retrieveValue<int>("./numThreads",numThreads);
		tempPointFileNameTemplate=cfg.retrieveValue<std::string>("./tempPointFileNameTemplate",tempPointFileNameTemplate);
		}
	catch(std::runtime_error err)
		{
		/* Just ignore the error */
		}
	
	/* Parse the command line and load the input files: */
	unsigned baseMemoryCacheSize=64; // Memory cache size for base octree in MB
	LidarProcessOctree* basePoints=0; // Octree containing the base point data
	const char* subtractFileName=0; // Name of ASCII file containing the point set to subtract
	int asciiColumnIndices[3]={0,1,2}; // Column indices of x, y, z point components in ASCII file
	Scalar epsilon=Scalar(1.0e-7); // Maximum match point distance
	PointAccumulator pa; // Point accumulator holding the subtracted point set
	pa.setMemorySize(memoryCacheSize,tempOctreeMaxNumPointsPerNode);
	pa.setTempOctreeFileNameTemplate(tempOctreeFileNameTemplate+"XXXXXX");
	PointAccumulator::Vector pointOffset=PointAccumulator::Vector::zero; // Offset vector added to points during octree creation
	const char* outputFileName=0; // Name of resulting LiDAR octree file
	bool haveOffset=false; // Flag whether an explicit point offset was specified on the command line
	
	for(int i=1;i<argc;++i)
		{
		if(argv[i][0]=='-')
			{
			if(strcasecmp(argv[i]+1,"o")==0)
				{
				++i;
				if(i<argc)
					outputFileName=argv[i];
				else
					std::cerr<<"Dangling -o flag on command line"<<std::endl;
				}
			else if(strcasecmp(argv[i]+1,"np")==0)
				{
				++i;
				if(i<argc)
					maxNumPointsPerNode=(unsigned int)(atoi(argv[i]));
				else
					std::cerr<<"Dangling -np flag on command line"<<std::endl;
				}
			else if(strcasecmp(argv[i]+1,"nt")==0)
				{
				++i;
				if(i<argc)
					numThreads=atoi(argv[i]);
				else
					std::cerr<<"Dangling -nt flag on command line"<<std::endl;
				}
			else if(strcasecmp(argv[i]+1,"ooc")==0)
				{
				++i;
				if(i<argc)
					{
					memoryCacheSize=(unsigned int)(atoi(argv[i]));
					pa.setMemorySize(memoryCacheSize,tempOctreeMaxNumPointsPerNode);
					}
				else
					std::cerr<<"Dangling -ooc flag on command line"<<std::endl;
				}
			else if(strcasecmp(argv[i]+1,"to")==0)
				{
				++i;
				if(i<argc)
					{
					tempOctreeFileNameTemplate=argv[i];
					pa.setTempOctreeFileNameTemplate(tempOctreeFileNameTemplate+"XXXXXX");
					}
				else
					std::cerr<<"Dangling -to flag on command line"<<std::endl;
				}
			else if(strcasecmp(argv[i]+1,"tp")==0)
				{
				++i;
				if(i<argc)
					tempPointFileNameTemplate=argv[i];
				else
					std::cerr<<"Dangling -tp flag on command line"<<std::endl;
				}
			else if(strcasecmp(argv[i]+1,"lasOffset")==0)
				{
				if(i+3<argc)
					{
					for(int j=0;j<3;++j)
						{
						++i;
						pointOffset[j]=atof(argv[i]);
						}
					haveOffset=true;
					}
				else
					std::cerr<<"Dangling -lasOffset flag on command line"<<std::endl;
				}
			else if(strcasecmp(argv[i]+1,"lasOffsetFile")==0)
				{
				++i;
				if(i<argc)
					{
					/* Read the point offset from a binary file: */
					try
						{
						IO::FilePtr offsetFile=IO::openFile(argv[i]);
						offsetFile->setEndianness(Misc::LittleEndian);
						offsetFile->read(pointOffset.getComponents(),3);
						haveOffset=true;
						}
					catch(std::runtime_error err)
						{
						/* Print a warning and carry on: */
						std::cerr<<"Ignoring lasOffsetFile argument due to error "<<err.what()<<" when reading file "<<argv[i]<<std::endl;
						}
					}
				else
					std::cerr<<"Dangling -lasOffsetFile flag on command line"<<std::endl;
				}
			else if(strcasecmp(argv[i]+1,"eps")==0)
				{
				++i;
				if(i<argc)
					epsilon=Scalar(atof(argv[i]));
				else
					std::cerr<<"Dangling -eps flag on command line"<<std::endl;
				}
			else if(strcasecmp(argv[i]+1,"booc")==0)
				{
				++i;
				if(i<argc)
					baseMemoryCacheSize=(unsigned int)(atoi(argv[i]));
				else
					std::cerr<<"Dangling -booc flag on command line"<<std::endl;
				}
			else if(strcasecmp(argv[i]+1,"columns")==0)
				{
				if(i+3<argc)
					{
					for(int j=0;j<3;++j)
						{
						++i;
						asciiColumnIndices[j]=atoi(argv[i]);
						}
					}
				else
					std::cerr<<"Dangling -columns flag on command line"<<std::endl;
				}
			}
		else if(basePoints==0)
			{
			try
				{
				/* Create a processing octree: */
				basePoints=new LidarProcessOctree(argv[i],size_t(baseMemoryCacheSize)*size_t(1024*1024));
				}
			catch(std::runtime_error err)
				{
				std::cerr<<"Cannot open LiDAR file "<<argv[i]<<" due to exception "<<err.what()<<"; terminating"<<std::endl;
				return 1;
				}
			}
		else if(subtractFileName==0)
			{
			/* Store the subtraction file name: */
			subtractFileName=argv[i];
			}
		else
			std::cerr<<"Ignoring command line argument "<<argv[i]<<std::endl;
		}
	
	if(!haveOffset)
		{
		/* Use the base point set's point offset for the resulting file: */
		pointOffset=-basePoints->getOffset();
		}
	else
		{
		PointAccumulator::Vector totalOffset=pointOffset-PointAccumulator::Vector(basePoints->getOffset());
		if(totalOffset!=PointAccumulator::Vector::zero)
			pa.setPointOffset(totalOffset);
		}
	
	/* Load the subtraction point set into a kd-tree: */
	std::vector<Point> subtractPoints;
	try
		{
		std::cout<<"Loading subtraction points from "<<subtractFileName<<"..."<<std::flush;
		IO::ValueSource subtractSource(new IO::ReadAheadFilter(IO::openFile(subtractFileName)));
		subtractSource.setWhitespace(',',true);
		subtractSource.setPunctuation('\n',true);
		subtractSource.skipWs();
		const LidarProcessOctree::OffsetVector& offset=basePoints->getOffset();
		while(!subtractSource.eof())
			{
			/* Read the next point and subtract the base file's point offset: */
			Point p;
			for(int i=0;i<3;++i)
				p[i]=Scalar(subtractSource.readNumber()-offset[i]);
			subtractPoints.push_back(p);

			/* Skip the rest of the line: */
			subtractSource.skipLine();
			subtractSource.skipWs();
			}
		std::cout<<" done"<<std::endl;
		}
	catch(std::runtime_error err)
		{
		std::cout<<" failed"<<std::endl;
		std::cerr<<"Caught exception "<<err.what()<<"while reading subtraction file "<<subtractFileName<<"; terminating"<<std::endl;
		return 1;
		}
	
	std::cout<<"Creating kd-tree of "<<subtractPoints.size()<<" subtraction points..."<<std::flush;
	Geometry::ArrayKdTree<Point>* subtractPointTree=new Geometry::ArrayKdTree<Point>(subtractPoints.size());
	Point* points=subtractPointTree->accessPoints();
	for(size_t i=0;i<subtractPoints.size();++i)
		points[i]=subtractPoints[i];
	subtractPointTree->releasePoints(numThreads);
	std::cout<<" done"<<std::endl;
	
	/* Process the base point set: */
	{
	std::cout<<"Subtracting points..."<<std::flush;
	NodePointSubtractor nps(*basePoints,*subtractPointTree,epsilon,pa);
	basePoints->processNodesPostfix(nps);
	pa.finishReading();
	std::cout<<" done"<<std::endl;
	}
	
	/* Clear input data structures: */
	delete basePoints;
	delete subtractPointTree;
	
	/* Construct an octree with less than maxPointsPerNode points per leaf: */
	LidarOctreeCreator tree(pa.getMaxNumCacheablePoints(),maxNumPointsPerNode,numThreads,pa.getTempOctrees(),tempPointFileNameTemplate+"XXXXXX");
	
	/* Delete the temporary point octrees: */
	pa.deleteTempOctrees();
	
	/* Write the octree structure and data to the destination LiDAR file: */
	tree.write(outputFileName);
	
	/* Check if a point offset was defined: */
	if(pointOffset!=PointAccumulator::Vector::zero)
		{
		/* Write the point offsets to an offset file: */
		std::string offsetFileName=outputFileName;
		offsetFileName.append("/Offset");
		IO::FilePtr offsetFile(IO::openFile(offsetFileName.c_str(),IO::File::WriteOnly));
		offsetFile->setEndianness(Misc::LittleEndian);
		offsetFile->write(pointOffset.getComponents(),3);
		}
	
	return 0;
	}