Ejemplo n.º 1
0
    void GlobalMap::read(ESM::GlobalMap& map)
    {
        const ESM::GlobalMap::Bounds& bounds = map.mBounds;

        if (bounds.mMaxX-bounds.mMinX < 0)
            return;
        if (bounds.mMaxY-bounds.mMinY < 0)
            return;

        if (bounds.mMinX > bounds.mMaxX
                || bounds.mMinY > bounds.mMaxY)
            throw std::runtime_error("invalid map bounds");

        if (!map.mImageData.size())
            return;

        Files::IMemStream istream(&map.mImageData[0], map.mImageData.size());

        osgDB::ReaderWriter* readerwriter = osgDB::Registry::instance()->getReaderWriterForExtension("png");
        if (!readerwriter)
        {
            std::cerr << "Can't read map overlay: no png readerwriter found" << std::endl;
            return;
        }

        osgDB::ReaderWriter::ReadResult result = readerwriter->readImage(istream);
        if (!result.success())
        {
            std::cerr << "Can't read map overlay: " << result.message() << " code " << result.status() << std::endl;
            return;
        }

        osg::ref_ptr<osg::Image> image = result.getImage();
        int imageWidth = image->s();
        int imageHeight = image->t();

        int xLength = (bounds.mMaxX-bounds.mMinX+1);
        int yLength = (bounds.mMaxY-bounds.mMinY+1);

        // Size of one cell in image space
        int cellImageSizeSrc = imageWidth / xLength;
        if (int(imageHeight / yLength) != cellImageSizeSrc)
            throw std::runtime_error("cell size must be quadratic");

        // If cell bounds of the currently loaded content and the loaded savegame do not match,
        // we need to resize source/dest boxes to accommodate
        // This means nonexisting cells will be dropped silently
        int cellImageSizeDst = mCellSize;

        // Completely off-screen? -> no need to blit anything
        if (bounds.mMaxX < mMinX
                || bounds.mMaxY < mMinY
                || bounds.mMinX > mMaxX
                || bounds.mMinY > mMaxY)
            return;

        int leftDiff = (mMinX - bounds.mMinX);
        int topDiff = (bounds.mMaxY - mMaxY);
        int rightDiff = (bounds.mMaxX - mMaxX);
        int bottomDiff =  (mMinY - bounds.mMinY);

        Box srcBox ( std::max(0, leftDiff * cellImageSizeSrc),
                                  std::max(0, topDiff * cellImageSizeSrc),
                                  std::min(imageWidth, imageWidth - rightDiff * cellImageSizeSrc),
                                  std::min(imageHeight, imageHeight - bottomDiff * cellImageSizeSrc));

        Box destBox ( std::max(0, -leftDiff * cellImageSizeDst),
                                   std::max(0, -topDiff * cellImageSizeDst),
                                   std::min(mWidth, mWidth + rightDiff * cellImageSizeDst),
                                   std::min(mHeight, mHeight + bottomDiff * cellImageSizeDst));

        osg::ref_ptr<osg::Texture2D> texture (new osg::Texture2D);
        texture->setImage(image);
        texture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE);
        texture->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE);
        texture->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR);
        texture->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);
        texture->setResizeNonPowerOfTwoHint(false);

        if (srcBox == destBox && imageWidth == mWidth && imageHeight == mHeight)
        {
            mOverlayImage->copySubImage(0, 0, 0, image);

            requestOverlayTextureUpdate(0, 0, mWidth, mHeight, texture, true, false);
        }
        else
        {
            // Dimensions don't match. This could mean a changed map region, or a changed map resolution.
            // In the latter case, we'll want filtering.
            // Create a RTT Camera and draw the image onto mOverlayImage in the next frame.
            requestOverlayTextureUpdate(destBox.mLeft, destBox.mTop, destBox.mRight-destBox.mLeft, destBox.mBottom-destBox.mTop, texture, true, true,
                                        srcBox.mLeft/float(imageWidth), srcBox.mTop/float(imageHeight),
                                        srcBox.mRight/float(imageWidth), srcBox.mBottom/float(imageHeight));
        }
    }
Ejemplo n.º 2
0
 CDLTransformRcPtr CDLTransform::CreateFromFile(const char * src, const char * cccid)
 {
     if(!src || (strlen(src) == 0) || !cccid)
     {
         std::ostringstream os;
         os << "Error loading CDL xml. ";
         os << "Source file not specified.";
         throw Exception(os.str().c_str());
     }
     
     // Check cache
     AutoMutex lock(g_cacheMutex);
     {
         CDLTransformMap::iterator iter = 
             g_cache.find(GetCDLLocalCacheKey(src,cccid));
         if(iter != g_cache.end())
         {
             return iter->second;
         }
     }
     
     std::ifstream istream(src);
     if(istream.fail()) {
         std::ostringstream os;
         os << "Error could not read CDL source file '" << src;
         os << "'. Please verify the file exists and appropriate ";
         os << "permissions are set.";
         throw Exception (os.str().c_str());
     }
     
     // Read the file into a string.
     std::ostringstream rawdata;
     rawdata << istream.rdbuf();
     std::string xml = rawdata.str();
     
     if(xml.empty())
     {
         std::ostringstream os;
         os << "Error loading CDL xml. ";
         os << "The specified source file, '";
         os << src << "' appears to be empty.";
         throw Exception(os.str().c_str());
     }
     
     TiXmlDocument doc;
     doc.Parse(xml.c_str());
     
     if(doc.Error())
     {
         std::ostringstream os;
         os << "Error loading CDL xml from file '";
         os << src << "'. ";
         os << doc.ErrorDesc() << " (line ";
         os << doc.ErrorRow() << ", character ";
         os << doc.ErrorCol() << ")";
         throw Exception(os.str().c_str());
     }
     
     if(!doc.RootElement())
     {
         std::ostringstream os;
         os << "Error loading CDL xml from file '";
         os << src << "'. ";
         os << "Please confirm the xml is valid.";
         throw Exception(os.str().c_str());
     }
     
     std::string rootValue = doc.RootElement()->Value();
     if(rootValue == "ColorCorrection")
     {
         // Load a single ColorCorrection into the cache
         CDLTransformRcPtr cdl = CDLTransform::Create();
         LoadCDL(cdl.get(), doc.RootElement()->ToElement());
         g_cache[GetCDLLocalCacheKey(src,cccid)] = cdl;
         return cdl;
     }
     else if(rootValue == "ColorCorrectionCollection")
     {
         // Load all CCs from the ColorCorrectionCollection
         // into the cache
         
         CDLTransformMap transforms;
         GetCDLTransforms(transforms, doc.RootElement());
         
         if(transforms.empty())
         {
             std::ostringstream os;
             os << "Error loading ccc xml. ";
             os << "No ColorCorrection elements found in file '";
             os << src << "'.";
             throw Exception(os.str().c_str());
         }
         
         for(CDLTransformMap::iterator iter = transforms.begin();
             iter != transforms.end();
             ++iter)
         {
             g_cache[GetCDLLocalCacheKey(src,iter->first)] = iter->second;
         }
         
         CDLTransformMap::iterator cciter = g_cache.find(GetCDLLocalCacheKey(src,cccid));
         if(cciter == g_cache.end())
         {
             std::ostringstream os;
             os << "Error loading ccc xml. ";
             os << "The specified cccid " << cccid << " ";
             os << "could not be found in file '";
             os << src << "'.";
             throw Exception(os.str().c_str());
         }
         
         return cciter->second;
     }
     
     std::ostringstream os;
     os << "Error loading CDL xml from file '";
     os << src << "'. ";
     os << "Root xml element is type '" << rootValue << "', ";
     os << "ColorCorrection or ColorCorrectionCollection expected.";
     throw Exception(os.str().c_str());
 }
Ejemplo n.º 3
0
bool get_address::from_data(uint32_t version, const data_chunk& data)
{
    data_source istream(data);
    return from_data(version, istream);
}
Ejemplo n.º 4
0
bool heading::from_data(const data_chunk& data)
{
    data_source istream(data);
    return from_data(istream);
}
Ejemplo n.º 5
0
bool header::from_data(uint32_t version, const data_chunk& data)
{
    data_source istream(data);
    return from_data(version, istream);
}
Ejemplo n.º 6
0
int main( int ac, char** av )
{
    try
    {
        comma::command_line_options options( ac, av );
        if( options.exists( "--help" ) || options.exists( "-h" ) || ac == 1 ) { usage(); }
        options.assert_mutually_exclusive( "--by-lower,--by-upper,--nearest" );
        bool by_upper = options.exists( "--by-upper" );
        bool nearest = options.exists( "--nearest" );
        bool by_lower = ( options.exists( "--by-lower" ) || !by_upper ) && !nearest;
        //bool nearest_only = options.exists( "--nearest-only" );
        bool timestamp_only = options.exists( "--timestamp-only,--time-only" );
        bool discard = !options.exists( "--no-discard" );
        boost::optional< boost::posix_time::time_duration > bound;
        if( options.exists( "--bound" ) ) { bound = boost::posix_time::microseconds( options.value< double >( "--bound" ) * 1000000 ); }
        comma::csv::options stdin_csv( options, "t" );
        //bool has_block = stdin_csv.has_field( "block" );
        comma::csv::input_stream< Point > stdin_stream( std::cin, stdin_csv );
        std::string properties = options.unnamed( "--by-lower,--by-upper,--nearest,--timestamp-only,--time-only,--no-discard", "--binary,-b,--delimiter,-d,--fields,-f,--bound" )[0];
        comma::io::istream is( comma::split( properties, ';' )[0] );
        comma::name_value::parser parser( "filename" );
        comma::csv::options csv = parser.get< comma::csv::options >( properties );
        if( csv.fields.empty() ) { csv.fields = "t"; }
        comma::csv::input_stream< Point > istream( *is, csv );
        std::pair< std::string, std::string > last;
        std::pair< boost::posix_time::ptime, boost::posix_time::ptime > last_timestamp;
        comma::signal_flag is_shutdown;
        while( !is_shutdown && std::cin.good() && !std::cin.eof() && is->good() && !is->eof() )
        {
            const Point* p = stdin_stream.read();
            if( !p ) { break; }
            bool eof = false;
            while( last_timestamp.first.is_not_a_date_time() || p->timestamp >= last_timestamp.second )
            {
                last_timestamp.first = last_timestamp.second;
                last.first = last.second;
                const Point* q = istream.read();
                if( !q ) { eof = true; break; }
                last_timestamp.second = q->timestamp;
                if( !timestamp_only )
                {
                    if( csv.binary() ) { last.second = std::string( istream.binary().last(), csv.format().size() ); }
                    else { last.second = comma::join( istream.ascii().last(), stdin_csv.delimiter ); }
                }
            }
            if( eof ) { break; }
            if( discard && p->timestamp < last_timestamp.first ) { continue; }
            bool is_first = by_lower || ( nearest && ( p->timestamp - last_timestamp.first ) < ( last_timestamp.second - p->timestamp ) );
            const boost::posix_time::ptime& t = is_first ? last_timestamp.first : last_timestamp.second;
            if( bound && !( ( t - *bound ) <= p->timestamp && p->timestamp <= ( t + *bound ) ) ) { continue; }
            const std::string& s = is_first ? last.first : last.second;
            if( stdin_csv.binary() )
            {
                std::cout.write( stdin_stream.binary().last(), stdin_csv.format().size() );
                if( timestamp_only )
                {
                    static comma::csv::binary< Point > b;
                    std::vector< char > v( b.format().size() );
                    b.put( Point( t ), &v[0] );
                    std::cout.write( &v[0], b.format().size() );
                }
                else
                {
                    std::cout.write( &s[0], s.size() );
                }
                std::cout.flush();
            }
            else
            {
                std::cout << comma::join( stdin_stream.ascii().last(), stdin_csv.delimiter );
                std::cout << stdin_csv.delimiter;
                if( timestamp_only ) { std::cout << boost::posix_time::to_iso_string( t ) << std::endl; }
                else { std::cout << s << std::endl; }
            }
        }
        if( is_shutdown ) { std::cerr << "csv-time-join: interrupted by signal" << std::endl; }
        return 0;     
    }
    catch( std::exception& ex ) { std::cerr << "csv-time-join: " << ex.what() << std::endl; }
    catch( ... ) { std::cerr << "csv-time-join: unknown exception" << std::endl; }
    usage();
}
Ejemplo n.º 7
0
    bool TransferProjectFile(wxString source, wxString target)
    {
        bool in_section = false;

        wxFileInputStream f_source(source);
        if (!f_source.Ok()) {
            wxLogMessage(wxT("Failed to read from %s"), source.c_str());
            return false;
        }
        wxFileOutputStream f_target(target);
        if (!f_target.Ok()) {
            wxLogMessage(wxT("Failed to write to %s"), target.c_str());
            return false;
        }

        CSettings *cfg = wxGetApp().GetSettings();
        wxTextInputStream istream(f_source);
        wxTextOutputStream ostream(f_target);
        for(;;) {
            wxString line = istream.ReadLine();

            if (f_source.Eof() && line.IsEmpty()) {
                break;
            }
            if (in_section) {
                if (line.StartsWith(wxT("Edit1="))) {
                    line.Empty();
                    /* If we have a first include path, add it first. */
                    if(!cfg->m_firstidir.IsEmpty()) {
                        line += cfg->m_firstidir + wxT(";");
                    }
                    /* Add the include path of the build tree. */
                    if (!::wxIsAbsolutePath(cfg->m_buildpath)) {
                        line += cfg->m_topdir + wxT("\\");
                    }
					line += cfg->m_buildpath + wxT("\\include;");
                    /* Add the ICC specific include path of the source tree. */
                    if (!::wxIsAbsolutePath(cfg->m_source_dir)) {
                        line += cfg->m_topdir + wxT("\\");
                    }
                    line += cfg->m_source_dir + wxT("\\include\\crt\\iccavr;");
                    /* Add the include path of the source tree. */
                    if (!::wxIsAbsolutePath(cfg->m_source_dir)) {
                        line += cfg->m_topdir + wxT("\\");
                    }
                    line += cfg->m_source_dir + wxT("\\include");
                    /* If we have a last include path, add it last. */
                    if(!cfg->m_lastidir.IsEmpty()) {
                        line += wxT(";") + cfg->m_lastidir;
                    }
                    line = wxT("Edit1=") + line;
                    line.Replace(wxT("/"), wxT("\\"));
                }
                else if (line.StartsWith(wxT("Edit2="))) {
                    line = wxT("Edit2=");
                    if (!::wxIsAbsolutePath(cfg->m_buildpath)) {
                        line += cfg->m_topdir + wxT("\\");
                    }
                    line += cfg->m_buildpath + wxT("\\lib");
                    line.Replace(wxT("/"), wxT("\\"));
                }
                else if (line.StartsWith(wxT("Edit3="))) {
                    NUTCOMPONENTOPTION *opt = m_doc->FindOptionByName(NULL, "PLATFORM");
                    line = wxT("Edit3=");
                    if (opt && opt->nco_enabled && opt->nco_active) {
                        if (opt->nco_value && opt->nco_value[0]) {
                            line += wxString(opt->nco_value, wxConvLocal) + wxT(" ");
                        } else {
                            char *value = GetConfigValueOrDefault(m_doc->GetRepository(), opt->nco_compo, opt->nco_name);
                            if (value) {
                                line += wxString(value, wxConvLocal) + wxT(" ");
                                free(value);
                            }
                        }
                    }
                    opt = m_doc->FindOptionByName(NULL, "MCU_ATMEGA2561");
                    if (opt == NULL) {
                        opt = m_doc->FindOptionByName(NULL, "MCU_ATMEGA2560");
                    }
                    if (opt && opt->nco_enabled && opt->nco_active) {
                        line += wxT("_MCU_extended");
                    }
                    else {
                        line += wxT("_MCU_enhanced");
                    }
                    line += wxT(" __HARVARD_ARCH__");
                    line += wxT(" ATMEGA");
                    line += wxT(" CONST=\"\"");
                }
                else if (line.StartsWith(wxT("Edit13="))) {
                    char *value = NULL;
                    NUTCOMPONENTOPTION *opt = m_doc->FindOptionByName(NULL, "ICCAVR_STARTUP");
                    line = wxT("Edit13=");

                    if (opt && opt->nco_enabled && opt->nco_active) {
                        if (opt->nco_value) {
                            value = strdup(opt->nco_value);
                        } else {
                            value = GetConfigValueOrDefault(m_doc->GetRepository(), opt->nco_compo, opt->nco_name);
                        }
                    }
                    wxString valstr;
                    if (value) {
                        valstr = wxString(value, wxConvLocal).Trim().Trim(false);
                        free(value);
                    }
                    if (valstr.IsEmpty()) {
                        line += wxT("crtenutram");
                    } else {
                        line += valstr;
                    }
                    line += wxT(".o");
                }
                else if (line.StartsWith(wxT("Edit27="))) {
                    line = wxT("Edit27=");
                    if (!::wxIsAbsolutePath(cfg->m_buildpath)) {
                        line += cfg->m_topdir + wxT("\\");
                    }
                    line += cfg->m_buildpath + wxT("\\lib\\nutinit.o");
                    line.Replace(wxT("/"), wxT("\\"));
                }
            }
            else if (line[0] == '[') {
                in_section = line.IsSameAs(wxT("[Compiler Options]"), false);
            }
            ostream.WriteString(line + wxT("\n"));
        }
        return true;
    }
Ejemplo n.º 8
0
bool version::from_data(const data_chunk& data)
{
    data_source istream(data);
    return from_data(istream);
}
Ejemplo n.º 9
0
AboutDolphin::AboutDolphin(wxWindow *parent, wxWindowID id,
		const wxString &title, const wxPoint &position,
		const wxSize& size, long style)
	: wxDialog(parent, id, title, position, size, style)
{
	const unsigned char* dolphin_logo_bin = dolphin_logo_png;
	size_t dolphin_logo_size = sizeof dolphin_logo_png;
#ifdef __APPLE__
	double scaleFactor = 1.0;
	if (GetContentScaleFactor() >= 2)
	{
		dolphin_logo_bin = dolphin_logo_2x_png;
		dolphin_logo_size = sizeof dolphin_logo_2x_png;
		scaleFactor = 2.0;
	}
#endif
	wxMemoryInputStream istream(dolphin_logo_bin, dolphin_logo_size);
	wxImage iDolphinLogo(istream, wxBITMAP_TYPE_PNG);
#ifdef __APPLE__
	wxGenericStaticBitmap* const sbDolphinLogo = new wxGenericStaticBitmap(this, wxID_ANY,
			wxBitmap(iDolphinLogo, -1, scaleFactor));
#else
	wxGenericStaticBitmap* const sbDolphinLogo = new wxGenericStaticBitmap(this, wxID_ANY,
			wxBitmap(iDolphinLogo));
#endif

	const wxString DolphinText = _("Dolphin");
	const wxString RevisionText = scm_desc_str;
	const wxString CopyrightText = _("(c) 2003-2015+ Dolphin Team. \"GameCube\" and \"Wii\" are trademarks of Nintendo. Dolphin is not affiliated with Nintendo in any way.");
	const wxString BranchText = wxString::Format(_("Branch: %s"), scm_branch_str);
	const wxString BranchRevText = wxString::Format(_("Revision: %s"), scm_rev_git_str);
	const wxString CompiledText = wxString::Format(_("Compiled: %s @ %s"), __DATE__, __TIME__);
	const wxString CheckUpdateText = _("Check for updates: ");
	const wxString Text = _("\n"
		"Dolphin is a free and open-source GameCube and Wii emulator.\n"
		"\n"
		"This software should not be used to play games you do not legally own.\n");
	const wxString LicenseText = _("License");
	const wxString AuthorsText = _("Authors");
	const wxString SupportText = _("Support");

	wxStaticText* const Dolphin = new wxStaticText(this, wxID_ANY, DolphinText);
	wxTextCtrl* const Revision = new wxTextCtrl(this, wxID_ANY, RevisionText, wxDefaultPosition, wxDefaultSize, wxNO_BORDER | wxTE_NO_VSCROLL);
	BanishBackground(Revision);
	wxStaticText* const Copyright = new wxStaticText(this, wxID_ANY, CopyrightText);
	wxTextCtrl* const Branch = new wxTextCtrl(this, wxID_ANY, "", wxDefaultPosition, wxSize(300, 50), wxNO_BORDER | wxTE_NO_VSCROLL);
	BanishBackground(Branch);
	wxStaticText* const Message = new wxStaticText(this, wxID_ANY, Text);
	wxStaticText* const UpdateText = new wxStaticText(this, wxID_ANY, CheckUpdateText);
	wxStaticText* const FirstSpacer = new wxStaticText(this, wxID_ANY, wxString("  |  "));
	wxStaticText* const SecondSpacer = new wxStaticText(this, wxID_ANY, wxString("  |  "));
	wxHyperlinkCtrl* const Download = new wxHyperlinkCtrl(this, wxID_ANY, "dolphin-emu.org/download", "https://dolphin-emu.org/download/");
	wxHyperlinkCtrl* const License = new wxHyperlinkCtrl(this, wxID_ANY, LicenseText, "https://github.com/dolphin-emu/dolphin/blob/master/license.txt");
	wxHyperlinkCtrl* const Authors = new wxHyperlinkCtrl(this, wxID_ANY, AuthorsText, "https://github.com/dolphin-emu/dolphin/graphs/contributors");
	wxHyperlinkCtrl* const Support = new wxHyperlinkCtrl(this, wxID_ANY, SupportText, "https://forums.dolphin-emu.org/");

	wxFont DolphinFont = Dolphin->GetFont();
	wxFont RevisionFont = Revision->GetFont();
	wxFont CopyrightFont = Copyright->GetFont();
	wxFont BranchFont = Branch->GetFont();

	DolphinFont.SetPointSize(36);
	Dolphin->SetFont(DolphinFont);

	RevisionFont.SetWeight(wxFONTWEIGHT_BOLD);
	Revision->SetFont(RevisionFont);

	Revision->SetEditable(false);
	Revision->SetWindowStyle(wxNO_BORDER);

	BranchFont.SetPointSize(7);
	Branch->SetFont(BranchFont);

	Branch->SetEditable(false);
	Branch->AppendText(BranchText + "\n");
	Branch->AppendText(BranchRevText + "\n");
	Branch->AppendText(CompiledText);

	CopyrightFont.SetPointSize(7);
	Copyright->SetFont(CopyrightFont);
	Copyright->SetFocus();

	wxBoxSizer* const sCheckUpdates = new wxBoxSizer(wxHORIZONTAL);
	sCheckUpdates->Add(UpdateText);
	sCheckUpdates->Add(Download);

	wxBoxSizer* const sLinks = new wxBoxSizer(wxHORIZONTAL);
	sLinks->Add(License);
	sLinks->Add(FirstSpacer);
	sLinks->Add(Authors);
	sLinks->Add(SecondSpacer);
	sLinks->Add(Support);

	wxBoxSizer* const sInfo = new wxBoxSizer(wxVERTICAL);
	sInfo->Add(Dolphin);
	sInfo->AddSpacer(5);
	sInfo->Add(Revision);
	sInfo->AddSpacer(10);
	sInfo->Add(Branch);
	sInfo->Add(sCheckUpdates);
	sInfo->Add(Message);
	sInfo->Add(sLinks);

	wxBoxSizer* const sLogo = new wxBoxSizer(wxVERTICAL);
	sLogo->AddSpacer(75);
	sLogo->Add(sbDolphinLogo);
	sLogo->AddSpacer(40);

	wxBoxSizer* const sMainHor = new wxBoxSizer(wxHORIZONTAL);
	sMainHor->AddSpacer(30);
	sMainHor->Add(sLogo);
	sMainHor->AddSpacer(30);
	sMainHor->Add(sInfo);
	sMainHor->AddSpacer(30);

	wxBoxSizer* const sFooter = new wxBoxSizer(wxVERTICAL);
	sFooter->AddSpacer(15);
	sFooter->Add(Copyright, 0, wxALIGN_BOTTOM | wxALIGN_CENTER);
	sFooter->AddSpacer(5);

	wxBoxSizer* const sMain = new wxBoxSizer(wxVERTICAL);
	sMain->Add(sMainHor, 1, wxEXPAND);
	sMain->Add(sFooter, 0, wxEXPAND);

	SetSizerAndFit(sMain);
	Center();
	SetFocus();
}
Ejemplo n.º 10
0
bool stealth_record::from_data(const data_chunk& data, bool wire)
{
    data_source istream(data);
    return from_data(istream, wire);
}
Ejemplo n.º 11
0
wxImage charArr2wxImage(const unsigned char * arg, int size)
{
    wxMemoryInputStream istream( arg, size );
    return wxImage( istream, wxBITMAP_TYPE_PNG );
}
Ejemplo n.º 12
0
int main( int argc, char** argv )
{
//     for( unsigned int i = 0; i < boost::lexical_cast< unsigned int >( argv[1] ); ++i )
//     {
//         double x = r() * 20 - 10;
//         double y = r() * 20 - 10;
//         double z = r() * 20 - 10;
//         std::cout << x << ',' << y << ',' << z << ',' << int( std::max( std::abs( x ), std::max( std::abs( y ), std::abs( z ) ) ) ) << std::endl;
//     }
//     return 0;

    try
    {
        std::string normal_string;
        std::string points_string;
        std::string point_outside;
        boost::program_options::options_description description( "options" );
        description.add_options()
            ( "help,h", "display help message" )
            ( "points,p", boost::program_options::value< std::string >( &points_string )->default_value( "0,0,0" ), "point(s) belonging to the plane, either 3 points, or 1 point, if --normal defined" )
            ( "point-outside", boost::program_options::value< std::string >( &point_outside ), "point on the side of the plane where the normal would point, a convenience option; 3 points are enough" )
            ( "normal,n", boost::program_options::value< std::string >( &normal_string ), "normal to the plane" )
            ( "intersections", "assume the input represents a trajectory, find all its intersections with the plane")
            ( "threshold", boost::program_options::value< double >(), "if --intersections present, any separation between contiguous points of trajectory greater than threshold will be treated as a gap in the trajectory (no intersections will lie in the gaps)");
        description.add( comma::csv::program_options::description( "x,y,z" ) );
        boost::program_options::variables_map vm;
        boost::program_options::store( boost::program_options::parse_command_line( argc, argv, description), vm );
        boost::program_options::notify( vm );
        if ( vm.count( "help" ) )
        {
            std::cerr << std::endl;
            std::cerr << "take points on stdin, append distance from a given plane" << std::endl;
            std::cerr << std::endl;
            std::cerr << "if --intersections is specified, assume the input represents a trajectory, find its intersections with the plane," << std::endl;
            std::cerr << "for each intersection, output adjacent points between which it occurs, the intersection point, and the direction of intersection (-1,0,+1)," << std::endl;
            std::cerr << "where 0 indicates that both adjacent points are in the plane, +1 if the trajectory's direction is the same as normal of the plane, and -1 otherwise" << std::endl;
            std::cerr << std::endl;
            std::cerr << "usage: " << std::endl;
            std::cerr << "    cat points.csv | points-slice [options] > points_with_distance.csv" << std::endl;
            std::cerr << "    cat trajectory.csv | points-slice [options] --intersections > intersections.csv" << std::endl;
            std::cerr << std::endl;
            std::cerr << description << std::endl;
            std::cerr << std::endl;
            std::cerr << "defining the plane" << std::endl;
            std::cerr << "    --points x1,y1,z1,x2,y2,z2,x3,y3,x3" << std::endl;
            std::cerr << "    --points x1,y1,z1,x2,y2,z2,x3,y3,x3 --point-outside x4,y4,z4" << std::endl;
            std::cerr << "    --points x,y,z --normal n1,n2,n3" << std::endl;
            std::cerr << "    --normal n1,n2,n3    (the plane passes through 0,0,0)" << std::endl;
            std::cerr << std::endl;
            std::cerr << "output" << std::endl;
            std::cerr << "    default: " << std::endl;
            std::cerr << "        x,y,z,distance, where distance is signed distance to the plane" << std::endl;
            std::cerr << std::endl;
            std::cerr << "    if --intersections is specified:" << std::endl;
            std::cerr << "        previous_input_line,input_line,intersection,direction" << std::endl;
            std::cerr << std::endl;
            std::cerr << "examples:" << std::endl;
            std::cerr << "   echo -e \"0,0,-1\\n0,0,0\\n0,0,1\" | points-slice --points 0,0,0,0,1,0,1,0,0" << std::endl;
            std::cerr << "   echo -e \"0,0,-1\\n0,0,0\\n0,0,1\" | points-slice --points 0,0,0,0,1,0,1,0,0 --point-outside 0,0,1" << std::endl;
            std::cerr << "   echo -e \"0,0,-1\\n0,0,0\\n0,0,1\" | points-slice --points 0,0,0 --normal 0,0,1" << std::endl;
            std::cerr << "   echo -e \"0,0,-1\\n0,0,0\\n0,0,1\" | points-slice --normal 0,0,1" << std::endl;
            std::cerr << "   echo -e \"0,0,-1\\n0,0,0\\n0,0,1\" | points-slice --normal 0,0,1 --intersections" << std::endl;
            std::cerr << "   echo -e \"0,0,-1\\n0,0,-0.5\\n0,0,0\\n0,0,1\\n0,0,1.5\" | points-slice --normal 0,0,1 --intersections --threshold=0.5" << std::endl;
            std::cerr << std::endl;
            return 1;
        }
        if( vm.count( "points" ) == 0 ) { std::cerr << "points-slice: please specify --points" << std::endl; return 1; }
        comma::csv::options csv = comma::csv::program_options::get( vm );
        Eigen::Vector3d normal;
        Eigen::Vector3d point;
        if( vm.count( "normal" ) )
        {
            normal = comma::csv::ascii< Eigen::Vector3d >( "x,y,z", ',' ).get( normal_string );
            point = comma::csv::ascii< Eigen::Vector3d >( "x,y,z", ',' ).get( points_string );
        }
        else
        {
            boost::array< Eigen::Vector3d, 3 > points; // quick and dirty
            std::vector< std::string > v = comma::split( points_string, ',' );
            if( v.size() != 9 ) { std::cerr << "points-slice: expected 3 points, got: \"" << points_string << "\"" << std::endl; return 1; }
            point = comma::csv::ascii< Eigen::Vector3d >( "x,y,z", ',' ).get( v[0] + ',' + v[1] + ',' + v[2] ); // quick and dirty
            Eigen::Vector3d a = comma::csv::ascii< Eigen::Vector3d >( "x,y,z", ',' ).get( v[3] + ',' + v[4] + ',' + v[5] ); // quick and dirty
            Eigen::Vector3d b = comma::csv::ascii< Eigen::Vector3d >( "x,y,z", ',' ).get( v[6] + ',' + v[7] + ',' + v[8] ); // quick and dirty
            a -= point;
            b -= point;
            if( comma::math::equal( std::abs( a.dot( b ) ), a.norm() * b.norm() ) ) { std::cerr << "points-slice: given points are not corners or a triangle: \"" << points_string << "\"" << std::endl; }
            normal = a.cross( b );
            if( vm.count( "point-outside" ) )
            {
                Eigen::Vector3d p = comma::csv::ascii< Eigen::Vector3d >( "x,y,z", ',' ).get( point_outside );
                if( comma::math::equal( ( p - point ).dot( normal ), 0 ) ) { std::cerr << "points-slice: expected a point outside of the plane, got: " << point_outside << ", which belongs to the plane" << std::endl; return 1; }
                normal *= normal.dot( p - point ) > 0 ? 1 : -1;
            }
        }
        normal.normalize();
        #ifdef WIN32
            _setmode( _fileno( stdout ), _O_BINARY ); /// @todo move to a library
        #endif
        comma::csv::input_stream< Eigen::Vector3d > istream( std::cin, csv, Eigen::Vector3d::Zero() );
        comma::signal_flag is_shutdown;
        comma::csv::ascii< Eigen::Vector3d > ascii( "x,y,z", csv.delimiter );
        comma::csv::binary< Eigen::Vector3d > binary( "3d", "x,y,z" );
        if( vm.count("intersections") )
        {
            Eigen::Hyperplane< double, 3 > plane( normal, point );
            boost::optional< Eigen::Vector3d > last;
            double d_last = 0;
            boost::optional< double > threshold;
            if( vm.count("threshold") ) { threshold.reset( vm["threshold"].as< double >() ); }
            std::string previous_line_ascii;
            std::vector< char > previous_data_binary;
            while( !is_shutdown && ( istream.ready() || ( !std::cin.eof() && std::cin.good() ) ) )
            {
                const Eigen::Vector3d* p = istream.read();
                if( !p ) { break; }
                double d = ( *p - point ).dot( normal );
                bool valid_intersection = false;
                if( last )
                {
                    bool intersects = d * d_last <= 0;
                    bool interval_within_threshold = !threshold || ( threshold && ( *p - *last ).norm() <= *threshold );
                    valid_intersection = intersects && interval_within_threshold;
                }
                if( valid_intersection )
                {
                    Eigen::Vector3d intersection_point;
                    BOOST_STATIC_ASSERT( sizeof( Eigen::Vector3d ) == sizeof( double ) * 3 );
                    bool lies_on_plane = ( d == 0 && d_last == 0 );
                    if( lies_on_plane )
                    {
                        intersection_point = *last; 
                    }
                    else
                    {
                        Eigen::ParametrizedLine< double, 3 > line = Eigen::ParametrizedLine< double, 3 >::Through( *last, *p );
                        intersection_point = line.intersectionPoint( plane );
                    }
                    comma::int32 direction;
                    if( d_last != 0 ) { direction = ( d_last < 0 ) ? 1 : -1; }
                    else if( d != 0 ) { direction = ( d > 0 ) ? 1 : -1; }
                    else { direction = 0; }
                    if( csv.binary() )
                    {
                        std::cout.write( &previous_data_binary[0], previous_data_binary.size() );
                        std::cout.write( istream.binary().last(), istream.binary().binary().format().size() );
                        std::cout.write( reinterpret_cast< const char* >( &intersection_point ), sizeof( double ) * 3 );
                        std::cout.write( reinterpret_cast< const char* >( &direction ), sizeof( comma::int32 ) );
                    }
                    else
                    {
                        std::cout << previous_line_ascii << csv.delimiter << comma::join( istream.ascii().last(), csv.delimiter ) << csv.delimiter
                                    << ascii.put( intersection_point ) << csv.delimiter << direction << std::endl;
                    }
                }
                last = *p;
                d_last = d;
                if( csv.binary() )
                {
                    if( previous_data_binary.size() != istream.binary().binary().format().size() )
                    {
                        previous_data_binary.resize( istream.binary().binary().format().size() );
                    }
                    ::memcpy( &previous_data_binary[0], istream.binary().last(), previous_data_binary.size() );
                }
                else
                {
                    previous_line_ascii = comma::join( istream.ascii().last(), csv.delimiter );
                }
            }
        }
        else
        {
            while( !is_shutdown && ( istream.ready() || ( !std::cin.eof() && std::cin.good() ) ) )
            {
                const Eigen::Vector3d* p = istream.read();
                if( !p ) { break; }
                double d = ( *p - point ).dot( normal );
                if( csv.binary() )
                {
                    std::cout.write( istream.binary().last(), istream.binary().binary().format().size() );
                    std::cout.write( reinterpret_cast< const char* >( &d ), sizeof( double ) );
                }
                else
                {
                    std::cout << comma::join( istream.ascii().last(), csv.delimiter ) << csv.delimiter << d << std::endl;
                }
            }
        }
        return 0;
    }
    catch( std::exception& ex )
    {
        std::cerr << "points-slice: " << ex.what() << std::endl;
    }
    catch( ... )
    {
        std::cerr << "points-slice: unknown exception" << std::endl;
    }
    return 1;
}
Ejemplo n.º 13
0
// constructor
// ------------------------------------------------------------------
rigctl::rigctl(QWidget * parent) : QDialog(parent),
settings(QSettings::IniFormat, QSettings::UserScope,"QtLog", "qtlog")
{
    setupUi(this);

    int n = settings.value("FontSize").toString().toInt();
    QFont font;
    font.setPointSize(n);
    setFont(font);
    
    connect(ButtonESC, SIGNAL(pressed()), this, SLOT(goExit()));
    connect(ButtonHilfe, SIGNAL(pressed()), this, SLOT(goHilfe()));
    connect(ButtonRigList, SIGNAL(pressed()), this, SLOT(showRigList()));
    connect(ButtonInit, SIGNAL(pressed()), this, SLOT(hamlibServerInit()));
    connect(ButtonStart, SIGNAL(pressed()), this, SLOT(goStart()));
    connect(ButtonStop, SIGNAL(pressed()), this, SLOT(goStop()));
    connect(buttonReturn, SIGNAL(pressed()), this, SLOT(showRigPage()));
    connect(InterfaceBox, SIGNAL(currentIndexChanged(QString)), this, SLOT(intefaceBoxChanged(QString)));
    connect(wrigList, SIGNAL(itemClicked(QTreeWidgetItem *,int)), this, SLOT(itemClickedCb(QTreeWidgetItem *,int)));
    
    tcpSocket = new QTcpSocket(this);              // tspSocket
    connect(tcpSocket, SIGNAL(connected()), this, SLOT(sentCommand()));
    connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(readRigReply()));
    connect(tcpSocket, SIGNAL(error(QAbstractSocket::SocketError)),
                                            this, SLOT(displayError(QAbstractSocket::SocketError)));     
    QString home = getenv("HOME");                 // lade alle devices
    s = "ls /dev/ttyS* > "+home+"/.qtlog/rigstatus";
    i = system(s.toAscii());                       // suche device ttyS0 .. n
    home += "/.qtlog/rigstatus";                   // prüfe rigstatus
    QFile iniFile(home);
    iniFile.open(QIODevice::ReadOnly);
    QTextStream istream( &iniFile);                // lese device_file
       
    RigDevBox->clear();
    PttBitDevBox->clear();
    i = 0;
    while(istream.atEnd() != true) {               // RigBox_dev füllen
       s = istream.readLine(0);
       RigDevBox->insertItem(i,s);
       PttBitDevBox->insertItem(i++,s);
    }
    iniFile.close();
         
    home = getenv("HOME"); 
    s = "ls /dev/ttyU* > "+home+"/.qtlog/rigstatus";
    n = system(s.toAscii());                       // suche device ttyUSB0 .. n
    home += "/.qtlog/rigstatus";
    QFile inuFile(home);
    inuFile.open(QIODevice::ReadOnly);
    QTextStream iustream( &inuFile);               // oeffne device_file
    while(iustream.atEnd() != true) {
      s = iustream.readLine(0);
      RigDevBox->insertItem(i,s);                  // alle vorhndenen USB0 .. n devices übenehmen
      PttBitDevBox->insertItem(i++,s);
    }
    inuFile.close();
    
    Retry = 0;
    Runing = 0;
    r = 0;
    Runing = -1;
    i = getRigModell();                                      // lade alle Rig_Modelle
    
    if(i != 0) {                                             // falls hamlib installiert ist - lade Rig_Modelle
      if(settings.value("RigPid").toString().count() != 0) { // und Rig configuriert wurde
       QSqlQuery query;                                      // hole config_parameter_discriptor
       qy = "SELECT * FROM wproz WHERE rigpid='"+settings.value("RigPid").toString()+"'";
       query.exec(qy);
       while(query.next()) {
          proz = query.value(r++).toString();              // proz
          owner = query.value(r++).toString();             // owner
          editRig->setText(query.value(r++).toString());   // Rig
          editPid->setText(query.value(r++).toString());   // Pid
          editRetry->setText(query.value(r++).toString()); // retry
          Retry = editRetry->text().toInt();
          i = RigDevBox->findText(query.value(r++).toString());
          RigDevBox->setCurrentIndex(i);                   // Rig_device_Box
          i = BaudBox->findText(query.value(r++).toString());
          BaudBox->setCurrentIndex(i);                     // Baud_device_box
	  // -
          i = InterfaceBox->findText(query.value(r++).toString()); // FAM_Interface ONE
          InterfaceBox->setCurrentIndex(i);
          i = PttBitDevBox->findText(query.value(r++).toString());
          PttBitDevBox->setCurrentIndex(i);                // PTT_device_Box
          editRts->setText(query.value(r++).toString());   // RTS = OFF
          editDtr->setText(query.value(r++).toString());   // DTR = OFF
          editCts->setText(query.value(r++).toString());   // CTS = OFF
	  // -
          if(InterfaceBox->currentText().compare("NO") == 0) {
            PttBitDevBox->setEnabled(FALSE);
            editRts->setEnabled(FALSE);
            editDtr->setEnabled(FALSE);
            editCts->setEnabled(FALSE);
          }
          editHost->setText(query.value(r++).toString());  // localhost
          editPort->setText(query.value(r++).toString());  // port
          Runing = query.value(r).toInt();                 // runing_bit
        }
      }
     
      updateFlg = 0;                                      // alles ok
      if( Runing == -1 )
         ButtonInit->setPalette( QPalette(QColor(180, 210, 200)));  // grün
      else
       if( Runing )
          ButtonStop->setPalette( QPalette(QColor(180, 210, 200))); // STOP grün
       else
         ButtonStart->setPalette( QPalette(QColor(180, 210, 200))); // grün
    }
    else 
       QTimer::singleShot(10, this, SLOT(hlibNoInstalled()));       // Hamlib nicht installiert
}
Ejemplo n.º 14
0
bool reject::from_data(const data_chunk& data)
{
    boost::iostreams::stream<byte_source<data_chunk>> istream(data);
    return from_data(istream);
}
Ejemplo n.º 15
0
int main( int argc, char** argv )
{
    try
    {
        comma::command_line_options options( argc, argv );
        if( options.exists( "--help,-h" ) ) { usage(); }
        if( options.exists( "--long-help" ) ) { usage( true ); }
        verbose = options.exists( "--verbose,-v" );
        comma::csv::options csv( options, "range,bearing,elevation" );
        std::vector< std::string > v = comma::split( csv.fields, ',' );
        for( unsigned int i = 0; i < v.size(); ++i )
        {
            if( v[i] == "r" ) { v[i] = "range"; }
            else if( v[i] == "b" ) { v[i] = "bearing"; }
            else if( v[i] == "e" ) { v[i] = "elevation"; }
        }
        csv.fields = comma::join( v, ',' );
        csv.full_xpath = false;
        double threshold = options.value< double >( "--angle-threshold,-a" );
        boost::optional< double > range_threshold = options.optional< double >( "--range-threshold,-r" );
        std::vector< std::string > unnamed = options.unnamed( "--verbose,-v", "--binary,-b,--delimiter,-d,--fields,-f,--range-threshold,-r,--angle-threshold,-a" );
        if( unnamed.empty() ) { std::cerr << "points-detect-change: please specify file with the reference point cloud" << std::endl; return 1; }
        if( unnamed.size() > 1 ) { std::cerr << "points-detect-change: expected file with the reference point cloud, got: " << comma::join( unnamed, ' ' ) << std::endl; return 1; }
        #ifdef WIN32
            std::ios::openmode mode = 0;
            if( csv.binary() )
            {
                mode |= std::ios::binary;
                _setmode( _fileno( stdin ), _O_BINARY );
                _setmode( _fileno( stdout ), _O_BINARY );
            }
            std::ifstream ifs( unnamed[0].c_str(), mode );
        #else
            std::ifstream ifs( unnamed[0].c_str() );
        #endif
        if( !ifs.is_open() ) { std::cerr << "points-detect-change: failed to open \"" << unnamed[0] << "\"" << std::endl; return 1; }
        comma::csv::input_stream< point_t > ifstream( ifs, csv );
        typedef snark::voxel_map< cell, 2 > grid_t;
        resolution = grid_t::point_type( threshold, threshold );
        grid_t grid( resolution );
        if( verbose ) { std::cerr << "points-detect-change: loading reference point cloud..." << std::endl; }
        comma::signal_flag is_shutdown;
        comma::uint64 index = 0;
        //{ ProfilerStart( "points-detect-change.prof" );
        std::deque< std::vector< char > > buffers;
        while( ifs.good() && !ifs.eof() && !is_shutdown )
        {
            const point_t* p = ifstream.read();
            if( !p ) { break; }
            cell::entry entry( *p, index );
            for( int i = -1; i < 2; ++i )
            {
                for( int j = -1; j < 2; ++j )
                {
                    double bearing = p->bearing() + threshold * i;
                    if( bearing < -M_PI ) { bearing += ( M_PI * 2 ); }
                    else if( bearing >= M_PI ) { bearing -= ( M_PI * 2 ); }
                    double elevation = p->elevation() + threshold * j;
                    grid_t::iterator it = grid.touch_at( grid_t::point_type( bearing, elevation ) );
                    it->second.add( entry ); //it->second.add_to_grid( entry );
                }
            }
            buffers.push_back( std::vector< char >() ); // todo: quick and dirty; use memory map instead?
            if( csv.binary() )
            {
                static unsigned int s = ifstream.binary().binary().format().size();
                buffers.back().resize( s );
                ::memcpy( &buffers.back()[0], ifstream.binary().last(), s );
            }
            else
            {
                std::string s = comma::join( ifstream.ascii().last(), csv.delimiter );
                buffers.back().resize( s.size() );
                ::memcpy( &buffers.back()[0], &s[0], s.size() );
            }
            ++index;
        }
        if( verbose ) { std::cerr << "points-detect-change: loaded reference point cloud: " << index << " points in a grid of size " << grid.size() << " voxels" << std::endl; }
        comma::csv::input_stream< point_t > istream( std::cin, csv );
        while( std::cin.good() && !std::cin.eof() && !is_shutdown )
        {
            const point_t* p = istream.read();
            if( !p ) { break; }
            grid_t::const_iterator it = grid.find( grid_t::point_type( p->bearing(), p->elevation() ) );
            if( it == grid.end() ) { continue; }
            const cell::entry* q = it->second.trace( *p, threshold, range_threshold );
            if( !q ) { continue; }
            if( csv.binary() )
            {
                static unsigned int is = istream.binary().binary().format().size();
                std::cout.write( istream.binary().last(), is );
                static unsigned int fs = ifstream.binary().binary().format().size();
                std::cout.write( &buffers[q->index][0], fs );
            }
            else
            {
                std::cout << comma::join( istream.ascii().last(), csv.delimiter )
                          << csv.delimiter
                          << std::string( &buffers[q->index][0], buffers[q->index].size() ) << std::endl;
            }
        }
        //} ProfilerStop();
        if( is_shutdown ) { std::cerr << "points-detect-change: caught signal" << std::endl; return 1; }
        return 0;
    }
    catch( std::exception& ex )
    {
        std::cerr << "points-detect-change: " << ex.what() << std::endl;
    }
    catch( ... )
    {
        std::cerr << "points-detect-change: unknown exception" << std::endl;
    }
    return 1;
}
Ejemplo n.º 16
0
static FIBITMAP * DLL_CALLCONV
Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
    bool bUseRgbaInterface = false;
    FIBITMAP *dib = NULL;

    if(!handle) {
        return NULL;
    }

    try {
        BOOL header_only = (flags & FIF_LOAD_NOPIXELS) == FIF_LOAD_NOPIXELS;

        // save the stream starting point
        const long stream_start = io->tell_proc(handle);

        // wrap the FreeImage IO stream
        C_IStream istream(io, handle);

        // open the file
        Imf::InputFile file(istream);

        // get file info
        const Imath::Box2i &dataWindow = file.header().dataWindow();
        int width  = dataWindow.max.x - dataWindow.min.x + 1;
        int height = dataWindow.max.y - dataWindow.min.y + 1;

        //const Imf::Compression &compression = file.header().compression();

        const Imf::ChannelList &channels = file.header().channels();

        // check the number of components and check for a coherent format

        std::string exr_color_model;
        Imf::PixelType pixel_type = Imf::HALF;
        FREE_IMAGE_TYPE image_type = FIT_UNKNOWN;
        int components = 0;
        bool bMixedComponents = false;

        for (Imf::ChannelList::ConstIterator i = channels.begin(); i != channels.end(); ++i) {
            components++;
            if(components == 1) {
                exr_color_model += i.name();
                pixel_type = i.channel().type;
            } else {
                exr_color_model += "/";
                exr_color_model += i.name();
                if (i.channel().type != pixel_type) {
                    bMixedComponents = true;
                }
            }
        }

        if(bMixedComponents) {
            bool bHandled = false;
            // we may have a RGBZ or RGBAZ image ...
            if(components > 4) {
                if(channels.findChannel("R") && channels.findChannel("G") && channels.findChannel("B") && channels.findChannel("A")) {
                    std::string msg = "Warning: converting color model " + exr_color_model + " to RGBA color model";
                    FreeImage_OutputMessageProc(s_format_id, msg.c_str());
                    bHandled = true;
                }
            }
            else if(components > 3) {
                if(channels.findChannel("R") && channels.findChannel("G") && channels.findChannel("B")) {
                    std::string msg = "Warning: converting color model " + exr_color_model + " to RGB color model";
                    FreeImage_OutputMessageProc(s_format_id, msg.c_str());
                    bHandled = true;
                }
            }
            if(!bHandled) {
                THROW (Iex::InputExc, "Unable to handle mixed component types (color model = " << exr_color_model << ")");
            }
        }

        switch(pixel_type) {
            case Imf::UINT:
                THROW (Iex::InputExc, "Unsupported format: UINT");
                break;
            case Imf::HALF:
            case Imf::FLOAT:
            default:
                break;
        }

        // check for supported image color models
        // --------------------------------------------------------------

        if((components == 1) || (components == 2)) {
            // if the image is gray-alpha (YA), ignore the alpha channel
            if((components == 1) && channels.findChannel("Y")) {
                image_type = FIT_FLOAT;
                components = 1;
            } else {
                std::string msg = "Warning: loading color model " + exr_color_model + " as Y color model";
                FreeImage_OutputMessageProc(s_format_id, msg.c_str());
                image_type = FIT_FLOAT;
                // ignore the other channel
                components = 1;
            }
        } else if(components == 3) {
            if(channels.findChannel("R") && channels.findChannel("G") && channels.findChannel("B")) {
                image_type = FIT_RGBF;
            }
            else if(channels.findChannel("BY") && channels.findChannel("RY") && channels.findChannel("Y")) {
                image_type = FIT_RGBF;
                bUseRgbaInterface = true;
            }
        } else if(components >= 4) {
            if(channels.findChannel("R") && channels.findChannel("G") && channels.findChannel("B")) {
                if(channels.findChannel("A")) {
                    if(components > 4) {
                        std::string msg = "Warning: converting color model " + exr_color_model + " to RGBA color model";
                        FreeImage_OutputMessageProc(s_format_id, msg.c_str());
                    }
                    image_type = FIT_RGBAF;
                    // ignore other layers if there is more than one alpha layer
                    components = 4;
                } else {
                    std::string msg = "Warning: converting color model " + exr_color_model + " to RGB color model";
                    FreeImage_OutputMessageProc(s_format_id, msg.c_str());

                    image_type = FIT_RGBF;
                    // ignore other channels
                    components = 3;
                }
            }
        }

        if(image_type == FIT_UNKNOWN) {
            THROW (Iex::InputExc, "Unsupported color model: " << exr_color_model);
        }

        // allocate a new dib
        dib = FreeImage_AllocateHeaderT(header_only, image_type, width, height, 0);
        if(!dib) THROW (Iex::NullExc, FI_MSG_ERROR_MEMORY);

        // try to load the preview image
        // --------------------------------------------------------------

        if(file.header().hasPreviewImage()) {
            const Imf::PreviewImage& preview = file.header().previewImage();
            const unsigned thWidth = preview.width();
            const unsigned thHeight = preview.height();

            FIBITMAP* thumbnail = FreeImage_Allocate(thWidth, thHeight, 32);
            if(thumbnail) {
                const Imf::PreviewRgba *src_line = preview.pixels();
                BYTE *dst_line = FreeImage_GetScanLine(thumbnail, thHeight - 1);
                const unsigned dstPitch = FreeImage_GetPitch(thumbnail);

                for (unsigned y = 0; y < thHeight; ++y) {
                    const Imf::PreviewRgba *src_pixel = src_line;
                    RGBQUAD* dst_pixel = (RGBQUAD*)dst_line;

                    for(unsigned x = 0; x < thWidth; ++x) {
                        dst_pixel->rgbRed = src_pixel->r;
                        dst_pixel->rgbGreen = src_pixel->g;
                        dst_pixel->rgbBlue = src_pixel->b;
                        dst_pixel->rgbReserved = src_pixel->a;
                        src_pixel++;
                        dst_pixel++;
                    }
                    src_line += thWidth;
                    dst_line -= dstPitch;
                }
                FreeImage_SetThumbnail(dib, thumbnail);
                FreeImage_Unload(thumbnail);
            }
        }

        if(header_only) {
            // header only mode
            return dib;
        }

        // load pixels
        // --------------------------------------------------------------

        const BYTE *bits = FreeImage_GetBits(dib);          // pointer to our pixel buffer
        const size_t bytespp = sizeof(float) * components;  // size of our pixel in bytes
        const unsigned pitch = FreeImage_GetPitch(dib);     // size of our yStride in bytes

        Imf::PixelType pixelType = Imf::FLOAT;  // load as float data type;

        if(bUseRgbaInterface) {
            // use the RGBA interface (used when loading RY BY Y images )

            const int chunk_size = 16;

            BYTE *scanline = (BYTE*)bits;

            // re-open using the RGBA interface
            io->seek_proc(handle, stream_start, SEEK_SET);
            Imf::RgbaInputFile rgbaFile(istream);

            // read the file in chunks
            Imath::Box2i dw = dataWindow;
            Imf::Array2D<Imf::Rgba> chunk(chunk_size, width);
            while (dw.min.y <= dw.max.y) {
                // read a chunk
                rgbaFile.setFrameBuffer (&chunk[0][0] - dw.min.x - dw.min.y * width, 1, width);
                rgbaFile.readPixels (dw.min.y, MIN(dw.min.y + chunk_size - 1, dw.max.y));
                // fill the dib
                const int y_max = ((dw.max.y - dw.min.y) <= chunk_size) ? (dw.max.y - dw.min.y) : chunk_size;
                for(int y = 0; y < y_max; y++) {
                    FIRGBF *pixel = (FIRGBF*)scanline;
                    const Imf::Rgba *half_rgba = chunk[y];
                    for(int x = 0; x < width; x++) {
                        // convert from half to float
                        pixel[x].red = half_rgba[x].r;
                        pixel[x].green = half_rgba[x].g;
                        pixel[x].blue = half_rgba[x].b;
                    }
                    // next line
                    scanline += pitch;
                }
                // next chunk
                dw.min.y += chunk_size;
            }

        } else {
            // use the low level interface

            // build a frame buffer (i.e. what we want on output)
            Imf::FrameBuffer frameBuffer;

            // allow dataWindow with minimal bounds different form zero
            size_t offset = - dataWindow.min.x * bytespp - dataWindow.min.y * pitch;

            if(components == 1) {
                frameBuffer.insert ("Y",    // name
                                    Imf::Slice (pixelType,  // type
                                                (char*)(bits + offset), // base
                                                bytespp,                // xStride
                                                pitch,                  // yStride
                                                1, 1,                   // x/y sampling
                                                0.0));                  // fillValue
            } else if((components == 3) || (components == 4)) {
                const char *channel_name[4] = { "R", "G", "B", "A" };

                for(int c = 0; c < components; c++) {
                    frameBuffer.insert (
                        channel_name[c],                    // name
                        Imf::Slice (pixelType,              // type
                                    (char*)(bits + c * sizeof(float) + offset), // base
                                    bytespp,                            // xStride
                                    pitch,                              // yStride
                                    1, 1,                               // x/y sampling
                                    0.0));                              // fillValue
                }
            }

            // read the file
            file.setFrameBuffer(frameBuffer);
            file.readPixels(dataWindow.min.y, dataWindow.max.y);
        }

        // lastly, flip dib lines
        FreeImage_FlipVertical(dib);

    }
    catch(Iex::BaseExc & e) {
        if(dib != NULL) {
            FreeImage_Unload(dib);
        }
        FreeImage_OutputMessageProc(s_format_id, e.what());
        return NULL;
    }

    return dib;
}
Ejemplo n.º 17
0
void TextArea::_updateLines()
{
    // check if already generated
    if (!_lines.empty()) return;

    _lines.resize(1);

    // here we respect only horizontal padding in order to properly wrap lines; vertical is handled on higher level
    int x = _paddingTopLeft.width(),
        y = 0,
        wordWidth = 0,
        maxWidth = _size.width() ? (_size.width() - _paddingBottomRight.width()) : 0;
    
    // Parsing lines of text
    // Cutting lines when it is needed (\n or when exceeding _width)
    std::istringstream istream(_text);
    std::string word, part;
    auto aFont = font();

    // on first iteation, process only leading whitespaces
    while (!istream.eof() && isspace((int)istream.peek()))
    {
        part.push_back((char)istream.get());
    }
    do
    {
        if (word.size() > 0)
        {
            // calculate word width
            wordWidth = 0;
            for (unsigned char ch : word)
            {
                wordWidth += aFont->glyphWidth(ch) + aFont->horizontalGap();
            }
            // switch to next line if word is too long
            if (_wordWrap && maxWidth && (x + wordWidth) > maxWidth)
            {
                part.push_back('\n');
            }
            part += word;
            // include trailing whitespaces
            while (!istream.eof() && isspace((int)istream.peek()))
            {
                part.push_back((char)istream.get());
            }
        }
        // place the part
        for (unsigned char ch : part)
        {
            if (ch == ' ')
            {
                x += aFont->spaceWidth() + aFont->horizontalGap();
            }

            if (ch == '\n' || (_wordWrap && maxWidth && x >= maxWidth))
            {
                _lines.back().width = x;
                x = 0;
                y += aFont->height() + aFont->verticalGap();
                _lines.emplace_back();
            }

            if (ch == ' ' || ch == '\n')
                continue;

            Line& line = _lines.back();
            Graphics::TextSymbol symbol {ch, {x, y}};
            line.symbols.push_back(symbol);
            x += aFont->glyphWidth(ch) + aFont->horizontalGap();
            line.width = x;
        }
        part.clear();

    } while (istream >> word);
}
Ejemplo n.º 18
0
void MeerkatNameHandler::request_finished(std::tr1::shared_ptr<HttpManager::HttpResponse> response,
        HttpManager::ERR_TYPE error, const boost::system::error_code& boost_error,
        std::tr1::shared_ptr<MetadataRequest> request, NameCallback callback) {

    std::tr1::shared_ptr<RemoteFileMetadata> bad;

    if (error == Transfer::HttpManager::REQUEST_PARSING_FAILED) {
        SILOG(transfer, error, "Request parsing failed during an HTTP name lookup (" << request->getURI() << ")");
        callback(bad);
        return;
    } else if (error == Transfer::HttpManager::RESPONSE_PARSING_FAILED) {
        SILOG(transfer, error, "Response parsing failed during an HTTP name lookup (" << request->getURI() << ")");
        callback(bad);
        return;
    } else if (error == Transfer::HttpManager::BOOST_ERROR) {
        SILOG(transfer, error, "A boost error happened during an HTTP name lookup (" << request->getURI() << "). Boost error = " << boost_error.message());
        callback(bad);
        return;
    } else if (error != HttpManager::SUCCESS) {
        SILOG(transfer, error, "An unknown error happened during an HTTP name lookup. (" << request->getURI() << ")");
        callback(bad);
        return;
    }

    if (response->getHeaders().size() == 0) {
        SILOG(transfer, error, "There were no headers returned during an HTTP name lookup (" << request->getURI() << ")");
        callback(bad);
        return;
    }

    HttpManager::Headers::const_iterator it;
    it = response->getHeaders().find("Content-Length");
    if (it != response->getHeaders().end()) {
        SILOG(transfer, error, "Content-Length header was present when it shouldn't be during an HTTP name lookup (" << request->getURI() << ")");
        callback(bad);
        return;
    }

    if (response->getStatusCode() != 200) {
        SILOG(transfer, error, "HTTP status code = " << response->getStatusCode() << " instead of 200 during an HTTP name lookup (" << request->getURI() << ")");
        callback(bad);
        return;
    }

    it = response->getHeaders().find("File-Size");
    if (it == response->getHeaders().end()) {
        SILOG(transfer, error, "Expected File-Size header not present during an HTTP name lookup (" << request->getURI() << ")");
        callback(bad);
        return;
    }
    std::string file_size_str = it->second;

    it = response->getHeaders().find("Hash");
    if (it == response->getHeaders().end()) {
        SILOG(transfer, error, "Expected Hash header not present during an HTTP name lookup (" << request->getURI() << ")");
        callback(bad);
        return;
    }
    std::string hash = it->second;

    if (response->getData()) {
        SILOG(transfer, error, "Body present during an HTTP name lookup (" << request->getURI() << ")");
        callback(bad);
        return;
    }

    Fingerprint fp;
    try {
        fp = Fingerprint::convertFromHex(hash);
    } catch(std::invalid_argument e) {
        SILOG(transfer, error, "Hash header didn't contain a valid Fingerprint string (" << request->getURI() << ")");
        callback(bad);
        return;
    }

    std::istringstream istream(file_size_str);
    uint64 file_size;
    istream >> file_size;
    std::ostringstream ostream;
    ostream << file_size;
    if(ostream.str() != file_size_str) {
        SILOG(transfer, error, "Error converting File-Size header string to integer (" << request->getURI() << ")");
        callback(bad);
        return;
    }

    //Just treat everything as a single chunk for now
    Range whole(0, file_size, LENGTH, true);
    Chunk chunk(fp, whole);
    ChunkList chunkList;
    chunkList.push_back(chunk);

    std::tr1::shared_ptr<RemoteFileMetadata> met(new RemoteFileMetadata(fp, request->getURI(),
            file_size, chunkList, response->getRawHeaders()));

    callback(met);
    SILOG(transfer, detailed, "done http name handler request_finished");
}
Ejemplo n.º 19
0
// Returns number of controls loaded, so 0 if failure
U32 LLControlGroup::loadFromFileLegacy(const std::string& filename, BOOL require_declaration, eControlType declare_as)
{
	std::string name;

	LLXmlTree xml_controls;

	if (!xml_controls.parseFile(filename))
	{
		llwarns << "Unable to open control file " << filename << llendl;
		return 0;
	}

	LLXmlTreeNode* rootp = xml_controls.getRoot();
	if (!rootp || !rootp->hasAttribute("version"))
	{
		llwarns << "No valid settings header found in control file " << filename << llendl;
		return 0;
	}

	U32		item = 0;
	U32		validitems = 0;
	S32 version;
	
	rootp->getAttributeS32("version", version);

	// Check file version
	if (version != CURRENT_VERSION)
	{
		llinfos << filename << " does not appear to be a version " << CURRENT_VERSION << " controls file" << llendl;
		return 0;
	}

	LLXmlTreeNode* child_nodep = rootp->getFirstChild();
	while(child_nodep)
	{
		name = child_nodep->getName();		
		
		BOOL declared = controlExists(name);

		if (require_declaration && !declared)
		{
			// Declaration required, but this name not declared.
			// Complain about non-empty names.
			if (!name.empty())
			{
				//read in to end of line
				llwarns << "LLControlGroup::loadFromFile() : Trying to set \"" << name << "\", setting doesn't exist." << llendl;
			}
			child_nodep = rootp->getNextChild();
			continue;
		}

		// Got an item.  Load it up.
		item++;

		// If not declared, assume it's a string
		if (!declared)
		{
			switch(declare_as)
			{
			case TYPE_COL4:
				declareColor4(name, LLColor4::white, LLStringUtil::null, NO_PERSIST);
				break;
			case TYPE_COL4U:
				declareColor4U(name, LLColor4U::white, LLStringUtil::null, NO_PERSIST);
				break;
			case TYPE_STRING:
			default:
				declareString(name, LLStringUtil::null, LLStringUtil::null, NO_PERSIST);
				break;
			}
		}

		// Control name has been declared in code.
		LLControlVariable *control = getControl(name);

		llassert(control);
		
		switch(control->mType)
		{
		case TYPE_F32:
			{
				F32 initial = 0.f;

				child_nodep->getAttributeF32("value", initial);

				control->set(initial);
				validitems++;
			}
			break;
		case TYPE_S32:
			{
				S32 initial = 0;

				child_nodep->getAttributeS32("value", initial);

				control->set(initial);
				validitems++;
			}
			break;
		case TYPE_U32:
			{
				U32 initial = 0;
				child_nodep->getAttributeU32("value", initial);
				control->set((LLSD::Integer) initial);
				validitems++;
			}
			break;
		case TYPE_BOOLEAN:
			{
				BOOL initial = FALSE;

				child_nodep->getAttributeBOOL("value", initial);
				control->set(initial);

				validitems++;
			}
			break;
		case TYPE_STRING:
			{
				std::string string;
				child_nodep->getAttributeString("value", string);
				control->set(string);
				validitems++;
			}
			break;
		case TYPE_VEC3:
			{
				LLVector3 vector;

				child_nodep->getAttributeVector3("value", vector);
				control->set(vector.getValue());
				validitems++;
			}
			break;
		case TYPE_VEC3D:
			{
				LLVector3d vector;

				child_nodep->getAttributeVector3d("value", vector);

				control->set(vector.getValue());
				validitems++;
			}
			break;
		case TYPE_RECT:
			{
				//RN: hack to support reading rectangles from a string
				std::string rect_string;

				child_nodep->getAttributeString("value", rect_string);
				std::istringstream istream(rect_string);
				S32 left, bottom, width, height;

				istream >> left >> bottom >> width >> height;

				LLRect rect;
				rect.setOriginAndSize(left, bottom, width, height);

				control->set(rect.getValue());
				validitems++;
			}
			break;
		case TYPE_COL4U:
			{
				LLColor4U color;

				child_nodep->getAttributeColor4U("value", color);
				control->set(color.getValue());
				validitems++;
			}
			break;
		case TYPE_COL4:
			{
				LLColor4 color;
				
				child_nodep->getAttributeColor4("value", color);
				control->set(color.getValue());
				validitems++;
			}
			break;
		case TYPE_COL3:
			{
				LLVector3 color;
				
				child_nodep->getAttributeVector3("value", color);
				control->set(LLColor3(color.mV).getValue());
				validitems++;
			}
			break;

		default:
		  break;

		}
	
		child_nodep = rootp->getNextChild();
	}

	return validitems;
}
Ejemplo n.º 20
0
bool block::from_data(const data_chunk& data)
{
    data_source istream(data);
    return from_data(istream);
}
Ejemplo n.º 21
0
int main( int ac, char** av )
{
    try
    {
        comma::command_line_options options( ac, av );
        verbose = options.exists( "--verbose,-v" );
        if( options.exists( "--help,-h" ) ) { usage( verbose ); }
        csv = comma::csv::options( options );
        csv.full_xpath = true;
        ascii = comma::csv::ascii< Eigen::Vector3d >( "x,y,z", csv.delimiter );
        const std::vector< std::string >& operations = options.unnamed( "--verbose,-v,--trace,--no-antialiasing,--next,--unit", "-.*" );
        if( operations.size() != 1 ) { std::cerr << "points-calc: expected one operation, got " << operations.size() << ": " << comma::join( operations, ' ' ) << std::endl; return 1; }
        const std::string& operation = operations[0];
        if (vector_calc::has_operation(operation))
        {
            vector_calc::process(operation, options, csv);
            return 0;
        }
        if( operation == "plane-intersection" )
        {
            plane_intersection::process(options, csv);
            return 0;
        }
        if( operation == "distance" )
        {
            if(    csv.has_field( "first" )   || csv.has_field( "second" )
                || csv.has_field( "first/x" ) || csv.has_field( "second/x" )
                || csv.has_field( "first/y" ) || csv.has_field( "second/y" )
                || csv.has_field( "first/z" ) || csv.has_field( "second/z" ) )
            {
                calculate_distance_for_pairs();
                return 0;
            }
            if ( options.exists( "--next" ) ) { calculate_distance_next(); }
            else { calculate_distance( false ); }
            return 0;
        }
        if( operation == "cumulative-distance" )
        {
            calculate_distance( true );
            return 0;
        }
        if( operation == "nearest" )
        {
            if( options.exists( "--point,--to" ) )
            {
                Eigen::Vector3d point = comma::csv::ascii< Eigen::Vector3d >().get( options.value< std::string >( "--point,--to" ) );
                comma::csv::input_stream< Eigen::Vector3d > istream( std::cin, csv );
                std::string record;
                double min_distance = std::numeric_limits< double >::max();
                while( istream.ready() || ( std::cin.good() && !std::cin.eof() ) )
                {
                    const Eigen::Vector3d* p = istream.read();
                    if( !p ) { break; }
                    double d = ( *p - point ).norm();
                    if( d >= min_distance ) { continue; }
                    min_distance = d;
                    record = csv.binary() ? std::string( istream.binary().last(), csv.format().size() ) : comma::join( istream.ascii().last(), csv.delimiter );
                }
                if( !record.empty() ) { std::cout << record; }
                if( csv.binary() ) { std::cout.write( reinterpret_cast< const char* >( &min_distance ), sizeof( double ) ); }
                else { std::cout << csv.delimiter << min_distance << std::endl; }
                return 0;
            }
            else
            {
                
                return 0;
            }
        }
        if( operation == "thin" )
        {
            if( !options.exists( "--resolution" ) ) { std::cerr << "points-calc: --resolution is not specified " << std::endl; return 1; }
            double resolution = options.value( "--resolution" , 0.0 );
            thin( resolution );
            return 0;
        }
        if( operation == "discretise" || operation == "discretize" )
        {
            if( !options.exists( "--step" ) ) { std::cerr << "points-calc: --step is not specified " << std::endl; return 1; }
            double step = options.value( "--step" , 0.0 );
            if( step <= 0 ) { std::cerr << "points-calc: expected positive step, got " << step << std::endl; return 1; }
            // the last discretised point can be very close to the end of the interval, in which case the last two points can be identical in the output since ascii.put uses 12 digits by default
            // setting --tolerance=1e-12 will not allow the last discretised point to be too close to the end of the interval and therefore the output will have two distinct points at the end
            double tolerance = options.value( "--tolerance" , 0.0 ); 
            if( tolerance < 0 ) { std::cerr << "points-calc: expected non-negative tolerance, got " << tolerance << std::endl; return 1; }
            discretise( step, tolerance );
            return 0;
        }
        if( operation == "local-max" || operation == "local-min" ) // todo: if( operation == "local-calc" ? )
        {
            double sign = operation == "local-max" ? 1 : -1;
            if( csv.fields.empty() ) { csv.fields = "x,y,z,scalar"; }
            csv.full_xpath = false;
            bool has_id = csv.has_field( "id" );
            comma::csv::input_stream< local_operation::point > istream( std::cin, csv );
            std::deque< local_operation::record > records;
            double radius = options.value< double >( "--radius" );
            bool trace = options.exists( "--trace" );
            Eigen::Vector3d resolution( radius, radius, radius );
            snark::math::closed_interval< double, 3 > extents;
            comma::uint32 id = 0;
            if( verbose ) { std::cerr << "points-calc: reading input points..." << std::endl; }
            while( istream.ready() || ( std::cin.good() && !std::cin.eof() ) )
            {
                const local_operation::point* p = istream.read();
                if( !p ) { break; }
                std::string line;
                if( csv.binary() ) // quick and dirty
                {
                    line.resize( csv.format().size() );
                    ::memcpy( &line[0], istream.binary().last(), csv.format().size() );
                }
                else
                {
                    line = comma::join( istream.ascii().last(), csv.delimiter );
                }
                local_operation::point q = *p;
                if( !has_id ) { q.id = id++; }
                records.push_back( local_operation::record( q, line ) );
                records.back().reference_record = &records.back();
                extents.set_hull( p->coordinates );
            }
            if( verbose ) { std::cerr << "points-calc: loading " << records.size() << " points into grid..." << std::endl; }
            typedef std::vector< local_operation::record* > voxel_t; // todo: is vector a good container? use deque
            typedef snark::voxel_map< voxel_t, 3 > grid_t;
            grid_t grid( extents.min(), resolution );
            for( std::size_t i = 0; i < records.size(); ++i ) { ( grid.touch_at( records[i].point.coordinates ) )->second.push_back( &records[i] ); }
            if( verbose ) { std::cerr << "points-calc: searching for local extrema..." << std::endl; }
            for( grid_t::iterator it = grid.begin(); it != grid.end(); ++it )
            {
                grid_t::index_type i;
                for( i[0] = it->first[0] - 1; i[0] < it->first[0] + 2; ++i[0] )
                {
                    for( i[1] = it->first[1] - 1; i[1] < it->first[1] + 2; ++i[1] )
                    {
                        for( i[2] = it->first[2] - 1; i[2] < it->first[2] + 2; ++i[2] )
                        {
                            grid_t::iterator git = grid.find( i );
                            if( git == grid.end() ) { continue; }
                            for( voxel_t::iterator vit = it->second.begin(); vit != it->second.end(); ++vit )
                            {
                                for( std::size_t k = 0; k < git->second.size() && ( *vit )->is_extremum; ++k )
                                {
                                    local_operation::evaluate_local_extremum( *vit, git->second[k], radius, sign );
                                }
                            }
                        }
                    }
                }
            }
            #ifdef WIN32
            _setmode( _fileno( stdout ), _O_BINARY );
            #endif
            if( verbose ) { std::cerr << "points-calc: filling extrema grid..." << std::endl; }
            grid_t extrema( extents.min(), resolution );
            for( std::size_t i = 0; i < records.size(); ++i )
            {
                if( records[i].is_extremum )
                { 
                    ( extrema.touch_at( records[i].point.coordinates ) )->second.push_back( &records[i] );
                }
                else
                { 
                    records[i].extremum_id = local_operation::record::invalid_id; // quick and dirty for now
//                     if( records[i].extremum_id == local_operation::record::invalid_id ) { continue; }
//                     while( records[i].reference_record->point.id != records[i].reference_record->reference_record->point.id )
//                     {
//                         records[i].reference_record = records[i].reference_record->reference_record;
//                     }
//                     records[i].extremum_id = records[i].reference_record->point.id;
                }
            }
            if( verbose ) { std::cerr << "points-calc: calculating distances to " << extrema.size() << " local extrema..." << std::endl; }
            for( grid_t::iterator it = grid.begin(); it != grid.end(); ++it )
            {
                grid_t::index_type i;
                for( i[0] = it->first[0] - 1; i[0] < it->first[0] + 2; ++i[0] )
                {
                    for( i[1] = it->first[1] - 1; i[1] < it->first[1] + 2; ++i[1] )
                    {
                        for( i[2] = it->first[2] - 1; i[2] < it->first[2] + 2; ++i[2] )
                        {
                            grid_t::iterator git = extrema.find( i );
                            if( git == extrema.end() ) { continue; }
                            for( std::size_t n = 0; n < it->second.size(); ++n )
                            {                            
                                for( std::size_t k = 0; k < git->second.size(); ++k )
                                {
                                    local_operation::update_nearest_extremum( it->second[n], git->second[k], radius );
                                }
                            }
                        }
                    }
                }
            }
            if( trace )
            {
                if( verbose ) { std::cerr << "points-calc: tracing extrema..." << std::endl; }
                for( std::size_t i = 0; i < records.size(); ++i )
                {
                    if( records[i].extremum_id == local_operation::record::invalid_id ) { continue; }
                    while( records[i].reference_record->point.id != records[i].reference_record->reference_record->point.id )
                    {
                        records[i].reference_record = records[i].reference_record->reference_record;
                    }
                }
            }
            if( verbose ) { std::cerr << "points-calc: outputting..." << std::endl; }
            std::string endl = csv.binary() ? "" : "\n";
            std::string delimiter = csv.binary() ? "" : std::string( 1, csv.delimiter );
            comma::csv::options output_csv;
            if( csv.binary() ) { output_csv.format( "ui,d" ); }
            comma::csv::output_stream< local_operation::output > ostream( std::cout, output_csv );
            for( std::size_t i = 0; i < records.size(); ++i )
            {
                std::cout.write( &records[i].line[0], records[i].line.size() );
                std::cout.write( &delimiter[0], delimiter.size() );
                ostream.write( records[i].output( false ) ); // quick and dirty
            }
            if( verbose ) { std::cerr << "points-calc: done!" << std::endl; }
            return 0;
        }
        if( operation == "nearest-max" || operation == "nearest-min" || operation == "nearest-any" )
        {
            double sign = operation == "nearest-max" ? 1 : -1;
            bool any = operation == "nearest-any";
            if( csv.fields.empty() ) { csv.fields = "x,y,z,scalar"; }
            csv.full_xpath = false;
            bool has_id = csv.has_field( "id" );
            comma::csv::input_stream< local_operation::point > istream( std::cin, csv );
            std::deque< local_operation::record > records;
            double radius = options.value< double >( "--radius" );
            Eigen::Vector3d resolution( radius, radius, radius );
            snark::math::closed_interval< double, 3 > extents;
            comma::uint32 id = 0;
            if( verbose ) { std::cerr << "points-calc: reading input points..." << std::endl; }
            while( istream.ready() || ( std::cin.good() && !std::cin.eof() ) )
            {
                const local_operation::point* p = istream.read();
                if( !p ) { break; }
                std::string line;
                if( csv.binary() ) // quick and dirty
                {
                    line.resize( csv.format().size() );
                    ::memcpy( &line[0], istream.binary().last(), csv.format().size() );
                }
                else
                {
                    line = comma::join( istream.ascii().last(), csv.delimiter );
                }
                local_operation::point q = *p;
                if( !has_id ) { q.id = id++; }
                records.push_back( local_operation::record( q, line ) );
                records.back().reference_record = &records.back();
                extents.set_hull( p->coordinates );
            }
            if( verbose ) { std::cerr << "points-calc: loading " << records.size() << " points into grid..." << std::endl; }
            typedef std::vector< local_operation::record* > voxel_t; // todo: is vector a good container? use deque
            typedef snark::voxel_map< voxel_t, 3 > grid_t;
            grid_t grid( extents.min(), resolution );
            for( std::size_t i = 0; i < records.size(); ++i ) { ( grid.touch_at( records[i].point.coordinates ) )->second.push_back( &records[i] ); }
            if( verbose ) { std::cerr << "points-calc: searching for " << operation << "..." << std::endl; }
            for( grid_t::iterator it = grid.begin(); it != grid.end(); ++it )
            {
                grid_t::index_type i;
                for( i[0] = it->first[0] - 1; i[0] < it->first[0] + 2; ++i[0] )
                {
                    for( i[1] = it->first[1] - 1; i[1] < it->first[1] + 2; ++i[1] )
                    {
                        for( i[2] = it->first[2] - 1; i[2] < it->first[2] + 2; ++i[2] )
                        {
                            grid_t::iterator git = grid.find( i );
                            if( git == grid.end() ) { continue; }
                            for( std::size_t n = 0; n < it->second.size(); ++n )
                            {                            
                                for( std::size_t k = 0; k < git->second.size(); ++k )
                                {
                                    local_operation::update_nearest( it->second[n], git->second[k], radius, sign, any );
                                }
                            }
                        }
                    }
                }
            }
            #ifdef WIN32
            _setmode( _fileno( stdout ), _O_BINARY );
            #endif
            if( verbose ) { std::cerr << "points-calc: outputting..." << std::endl; }
            std::string endl = csv.binary() ? "" : "\n";
            std::string delimiter = csv.binary() ? "" : std::string( 1, csv.delimiter );
            comma::csv::options output_csv;
            if( csv.binary() ) { output_csv.format( "ui,d" ); }
            comma::csv::output_stream< local_operation::output > ostream( std::cout, output_csv );
            for( std::size_t i = 0; i < records.size(); ++i )
            {
                std::cout.write( &records[i].line[0], records[i].line.size() );
                std::cout.write( &delimiter[0], delimiter.size() );
                ostream.write( records[i].output() );
            }
            if( verbose ) { std::cerr << "points-calc: done!" << std::endl; }
            return 0;
        }
        if( operation == "find-outliers" )
        {
            unsigned int size = options.value< unsigned int >( "--min-number-of-points-per-voxel,--size" );
            double r = options.value< double >( "--resolution" );
            Eigen::Vector3d resolution( r, r, r );
            bool no_antialiasing = options.exists( "--no-antialiasing" );            
            comma::csv::input_stream< Eigen::Vector3d > istream( std::cin, csv );
            std::deque< remove_outliers::record > records;
            snark::math::closed_interval< double, 3 > extents;
            if( verbose ) { std::cerr << "points-calc: reading input points..." << std::endl; }
            while( istream.ready() || ( std::cin.good() && !std::cin.eof() ) )
            {
                const Eigen::Vector3d* p = istream.read();
                if( !p ) { break; }
                std::string line;
                if( csv.binary() ) // quick and dirty
                {
                    line.resize( csv.format().size() );
                    ::memcpy( &line[0], istream.binary().last(), csv.format().size() );
                }
                else
                {
                    line = comma::join( istream.ascii().last(), csv.delimiter );
                }
                records.push_back( remove_outliers::record( *p, line ) );
                extents.set_hull( *p );
            }
            if( verbose ) { std::cerr << "points-calc: loading " << records.size() << " points into grid..." << std::endl; }
            typedef std::vector< remove_outliers::record* > voxel_t; // todo: is vector a good container? use deque
            typedef snark::voxel_map< voxel_t, 3 > grid_t;
            grid_t grid( extents.min(), resolution );
            for( std::size_t i = 0; i < records.size(); ++i ) { ( grid.touch_at( records[i].point ) )->second.push_back( &records[i] ); }
            if( verbose ) { std::cerr << "points-calc: removing outliers..." << std::endl; }
            for( grid_t::iterator it = grid.begin(); it != grid.end(); ++it )
            {
                bool rejected = true;
                if( no_antialiasing )
                {
                    rejected = it->second.size() < size;
                }
                else
                {
                    grid_t::index_type i;
                    for( i[0] = it->first[0] - 1; i[0] < it->first[0] + 2 && rejected; ++i[0] )
                    {
                        for( i[1] = it->first[1] - 1; i[1] < it->first[1] + 2 && rejected; ++i[1] )
                        {
                            for( i[2] = it->first[2] - 1; i[2] < it->first[2] + 2 && rejected; ++i[2] )
                            {
                                grid_t::iterator git = grid.find( i );
                                rejected = git == grid.end() || git->second.size() < size;
                            }
                        }
                    }
                }
                if( rejected ) { for( std::size_t i = 0; i < it->second.size(); ++i ) { it->second[i]->rejected = true; } }
            }
            #ifdef WIN32
            _setmode( _fileno( stdout ), _O_BINARY );
            #endif
            if( verbose ) { std::cerr << "points-calc: outputting..." << std::endl; }
            std::string endl = csv.binary() ? "" : "\n";
            std::string delimiter = csv.binary() ? "" : std::string( 1, csv.delimiter );
            for( std::size_t i = 0; i < records.size(); ++i )
            {
                char valid = records[i].rejected ? 0 : 1;
                std::cout.write( &records[i].line[0], records[i].line.size() );
                std::cout.write( &delimiter[0], delimiter.size() );
                std::cout.write( &valid, 1 );
                std::cout.write( &endl[0], endl.size() );
            }
            if( verbose ) { std::cerr << "points-calc: done!" << std::endl; }
            return 0;
        }
        std::cerr << "points-calc: please specify an operation" << std::endl;
        return 1;
    }
    catch( std::exception& ex )
    {
        std::cerr << "points-calc: " << ex.what() << std::endl;
    }
    catch( ... )
    {
        std::cerr << "points-calc: unknown exception" << std::endl;
    }
    return 1;
}