<commit_before>/*
 * Copyright (c) 2008, Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include "platform/fonts/win/SkiaFontWin.h"

#include "platform/fonts/SimpleFontData.h"
#include "platform/fonts/win/FontPlatformDataWin.h"
#include "platform/graphics/Gradient.h"
#include "platform/graphics/GraphicsContext.h"
#include "platform/graphics/Pattern.h"
#include "platform/transforms/AffineTransform.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkDevice.h"
#include "third_party/skia/include/core/SkPaint.h"
#include "third_party/skia/include/core/SkShader.h"
#include "third_party/skia/include/core/SkTemplates.h"
#include "wtf/RefPtr.h"

namespace WebCore {

static void skiaDrawText(GraphicsContext* context,
    const SkPoint& point,
    const SkRect& textRect,
    SkPaint* paint,
    const WORD* glyphs,
    const int* advances,
    const GOFFSET* offsets,
    unsigned numGlyphs)
{
    // Reserve space for 64 SkPoints on the stack. If numGlyphs is larger, the array
    // will dynamically allocate it space for numGlyph glyphs. This is used to store
    // the computed x,y locations. In the case where offsets==null, then we use it
    // to store (twice as many) SkScalars for x[]
    static const size_t kLocalGlyphMax = 64;

    SkScalar x = point.fX;
    SkScalar y = point.fY;
    if (offsets) {
        SkAutoSTArray<kLocalGlyphMax, SkPoint> storage(numGlyphs);
        SkPoint* pos = storage.get();
        for (unsigned i = 0; i < numGlyphs; i++) {
            // GDI has dv go up, so we negate it
            pos[i].set(x + SkIntToScalar(offsets[i].du), y + -SkIntToScalar(offsets[i].dv));
            x += SkIntToScalar(advances[i]);
        }
        context->drawPosText(glyphs, numGlyphs * sizeof(uint16_t), pos, textRect, *paint);
    } else {
        SkAutoSTArray<kLocalGlyphMax * 2, SkScalar> storage(numGlyphs);
        SkScalar* xpos = storage.get();
        for (unsigned i = 0; i < numGlyphs; i++) {
            xpos[i] = x;
            x += SkIntToScalar(advances[i]);
        }
        context->drawPosTextH(glyphs, numGlyphs * sizeof(uint16_t), xpos, y, textRect, *paint);
    }
}

static void paintSkiaText(GraphicsContext* context,
    const FontPlatformData& data,
    SkTypeface* face, float size, uint32_t textFlags,
    unsigned numGlyphs,
    const WORD* glyphs,
    const int* advances,
    const GOFFSET* offsets,
    const SkPoint& origin,
    const SkRect& textRect)
{
    TextDrawingModeFlags textMode = context->textDrawingMode();

    // Filling (if necessary). This is the common case.
    SkPaint paint;
    context->setupPaintForFilling(&paint);
    paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
    data.setupPaint(&paint, context);

    // FIXME: Only needed to support the HFONT based paintSkiaText
    // version where a new typeface is created from the HFONT.
    // As such it can go away once the HFONT code path is removed.
    paint.setTypeface(face);

    bool didFill = false;

    if ((textMode & TextModeFill) && (SkColorGetA(paint.getColor()) || paint.getLooper())) {
        skiaDrawText(context, origin, textRect, &paint, &glyphs[0], &advances[0], &offsets[0], numGlyphs);
        didFill = true;
    }

    // Stroking on top (if necessary).
    if ((textMode & TextModeStroke)
        && context->strokeStyle() != NoStroke
        && context->strokeThickness() > 0) {

        paint.reset();
        context->setupPaintForStroking(&paint);
        paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
        data.setupPaint(&paint, context);
        paint.setTypeface(face);

        if (didFill) {
            // If there is a shadow and we filled above, there will already be
            // a shadow. We don't want to draw it again or it will be too dark
            // and it will go on top of the fill.
            //
            // Note that this isn't strictly correct, since the stroke could be
            // very thick and the shadow wouldn't account for this. The "right"
            // thing would be to draw to a new layer and then draw that layer
            // with a shadow. But this is a lot of extra work for something
            // that isn't normally an issue.
            paint.setLooper(0);
        }

        skiaDrawText(context, origin, textRect, &paint, &glyphs[0], &advances[0], &offsets[0], numGlyphs);
    }
}

///////////////////////////////////////////////////////////////////////////////////////////

void paintSkiaText(GraphicsContext* context,
    const FontPlatformData& data,
    unsigned numGlyphs,
    const WORD* glyphs,
    const int* advances,
    const GOFFSET* offsets,
    const SkPoint& origin,
    const SkRect& textRect)
{
    paintSkiaText(context, data, data.typeface(), data.size(), data.paintTextFlags(),
        numGlyphs, glyphs, advances, offsets, origin, textRect);
}

} // namespace WebCore
<commit_msg>Remove unnecessary paintSkiaText wrapper<commit_after>/*
 * Copyright (c) 2008, Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include "platform/fonts/win/SkiaFontWin.h"

#include "platform/fonts/SimpleFontData.h"
#include "platform/fonts/win/FontPlatformDataWin.h"
#include "platform/graphics/Gradient.h"
#include "platform/graphics/GraphicsContext.h"
#include "platform/graphics/Pattern.h"
#include "platform/transforms/AffineTransform.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkDevice.h"
#include "third_party/skia/include/core/SkPaint.h"
#include "third_party/skia/include/core/SkShader.h"
#include "third_party/skia/include/core/SkTemplates.h"
#include "wtf/RefPtr.h"

namespace WebCore {

static void skiaDrawText(GraphicsContext* context,
    const SkPoint& point,
    const SkRect& textRect,
    SkPaint* paint,
    const WORD* glyphs,
    const int* advances,
    const GOFFSET* offsets,
    unsigned numGlyphs)
{
    // Reserve space for 64 SkPoints on the stack. If numGlyphs is larger, the array
    // will dynamically allocate it space for numGlyph glyphs. This is used to store
    // the computed x,y locations. In the case where offsets==null, then we use it
    // to store (twice as many) SkScalars for x[]
    static const size_t kLocalGlyphMax = 64;

    SkScalar x = point.fX;
    SkScalar y = point.fY;
    if (offsets) {
        SkAutoSTArray<kLocalGlyphMax, SkPoint> storage(numGlyphs);
        SkPoint* pos = storage.get();
        for (unsigned i = 0; i < numGlyphs; i++) {
            // GDI has dv go up, so we negate it
            pos[i].set(x + SkIntToScalar(offsets[i].du), y + -SkIntToScalar(offsets[i].dv));
            x += SkIntToScalar(advances[i]);
        }
        context->drawPosText(glyphs, numGlyphs * sizeof(uint16_t), pos, textRect, *paint);
    } else {
        SkAutoSTArray<kLocalGlyphMax * 2, SkScalar> storage(numGlyphs);
        SkScalar* xpos = storage.get();
        for (unsigned i = 0; i < numGlyphs; i++) {
            xpos[i] = x;
            x += SkIntToScalar(advances[i]);
        }
        context->drawPosTextH(glyphs, numGlyphs * sizeof(uint16_t), xpos, y, textRect, *paint);
    }
}

void paintSkiaText(GraphicsContext* context,
    const FontPlatformData& data,
    unsigned numGlyphs,
    const WORD* glyphs,
    const int* advances,
    const GOFFSET* offsets,
    const SkPoint& origin,
    const SkRect& textRect)
{
    TextDrawingModeFlags textMode = context->textDrawingMode();

    // Filling (if necessary). This is the common case.
    SkPaint paint;
    context->setupPaintForFilling(&paint);
    paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
    data.setupPaint(&paint, context);

    bool didFill = false;

    if ((textMode & TextModeFill) && (SkColorGetA(paint.getColor()) || paint.getLooper())) {
        skiaDrawText(context, origin, textRect, &paint, &glyphs[0], &advances[0], &offsets[0], numGlyphs);
        didFill = true;
    }

    // Stroking on top (if necessary).
    if ((textMode & TextModeStroke)
        && context->strokeStyle() != NoStroke
        && context->strokeThickness() > 0) {

        paint.reset();
        context->setupPaintForStroking(&paint);
        paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
        data.setupPaint(&paint, context);

        if (didFill) {
            // If there is a shadow and we filled above, there will already be
            // a shadow. We don't want to draw it again or it will be too dark
            // and it will go on top of the fill.
            //
            // Note that this isn't strictly correct, since the stroke could be
            // very thick and the shadow wouldn't account for this. The "right"
            // thing would be to draw to a new layer and then draw that layer
            // with a shadow. But this is a lot of extra work for something
            // that isn't normally an issue.
            paint.setLooper(0);
        }

        skiaDrawText(context, origin, textRect, &paint, &glyphs[0], &advances[0], &offsets[0], numGlyphs);
    }
}

} // namespace WebCore
<|endoftext|>


<commit_before>#include "utf8_string.hpp"

#include "../std/iterator.hpp"

#include "../3party/utfcpp/source/utf8/unchecked.h"

namespace utf8_string
{
  bool Split(string const & str, vector<string> & out, IsDelimiterFuncT f)
  {
    out.clear();
    string::const_iterator curr = str.begin();
    string::const_iterator end = str.end();
    string word;
    back_insert_iterator<string> inserter = back_inserter(word);
    while (curr != end)
    {
      uint32_t symbol = ::utf8::unchecked::next(curr);
      if (f(symbol))
      {
        if (!word.empty())
        {
          out.push_back(word);
          word.clear();
          inserter = back_inserter(word);
        }
      }
      else
      {
        inserter = utf8::unchecked::append(symbol, inserter);
      }
    }
    if (!word.empty())
      out.push_back(word);
    return !out.empty();
  }

  bool IsSearchDelimiter(uint32_t symbol)
  {
    // latin table optimization
    if (symbol >= ' ' && symbol < '0')
      return true;

    switch (symbol)
    {
    case ':':
    case ';':
    case '[':
    case ']':
    case '\\':
    case '^':
    case '_':
    case '`':
    case '{':
    case '}':
    case '|':
    case '~':
    case 0x0336:
      return true;
    }
    return false;
  }
}
<commit_msg>Add '<', '=', '>' as search delimeters.<commit_after>#include "utf8_string.hpp"

#include "../std/iterator.hpp"

#include "../3party/utfcpp/source/utf8/unchecked.h"

namespace utf8_string
{
  bool Split(string const & str, vector<string> & out, IsDelimiterFuncT f)
  {
    out.clear();
    string::const_iterator curr = str.begin();
    string::const_iterator end = str.end();
    string word;
    back_insert_iterator<string> inserter = back_inserter(word);
    while (curr != end)
    {
      uint32_t symbol = ::utf8::unchecked::next(curr);
      if (f(symbol))
      {
        if (!word.empty())
        {
          out.push_back(word);
          word.clear();
          inserter = back_inserter(word);
        }
      }
      else
      {
        inserter = utf8::unchecked::append(symbol, inserter);
      }
    }
    if (!word.empty())
      out.push_back(word);
    return !out.empty();
  }

  bool IsSearchDelimiter(uint32_t symbol)
  {
    // latin table optimization
    if (symbol >= ' ' && symbol < '0')
      return true;

    switch (symbol)
    {
    case ':':
    case ';':
    case '<':
    case '=':
    case '>':
    case '[':
    case ']':
    case '\\':
    case '^':
    case '_':
    case '`':
    case '{':
    case '}':
    case '|':
    case '~':
    case 0x0336:
      return true;
    }
    return false;
  }
}
<|endoftext|>


<commit_before>#ifndef BNI_UTILITY_HPP
#define BNI_UTILITY_HPP

#include <string>
#include <vector>
#include <bayesian/graph.hpp>

namespace bn {
namespace io {

template<class InputStream>
std::vector<std::string> stream_to_lines(InputStream& is)
{
    std::vector<std::string> result;
    std::string line;
    while(std::getline(is, line))
    {
        if(line.back() == '¥r') line.pop_back();
        result.push_back(line);
    }

    return result;
}

// template使って書きたさしかない
// つーかゴリ押し
class dsc {
public:
    graph_t parse(std::vector<std::string> data);
    graph_t from_file(std::string const& filename);
    graph_t from_data(std::string const& data);

private:
    typedef std::vector<std::string>::iterator LineIterator;

    void parse_header(LineIterator& it, LineIterator const& end);
    void parse_node(LineIterator& it, LineIterator const& end);
    void parse_cpt(LineIterator& it, LineIterator const& end);

    graph_t graph_;
    std::unordered_map<std::string, vertex_type> dictionary_;
};

} // namespace io
} // namespace bn

#endif // #ifndef BNI_UTILITY_HPP
<commit_msg>Fix for Windows around \r\n again.<commit_after>#ifndef BNI_UTILITY_HPP
#define BNI_UTILITY_HPP

#include <string>
#include <vector>
#include <bayesian/graph.hpp>

namespace bn {
namespace io {

template<class InputStream>
std::vector<std::string> stream_to_lines(InputStream& is)
{
    std::vector<std::string> result;
    std::string line;
    while(std::getline(is, line))
    {
        if(!line.empty() && line.back() == '¥r') line.pop_back();
        result.push_back(line);
    }

    return result;
}

// template使って書きたさしかない
// つーかゴリ押し
class dsc {
public:
    graph_t parse(std::vector<std::string> data);
    graph_t from_file(std::string const& filename);
    graph_t from_data(std::string const& data);

private:
    typedef std::vector<std::string>::iterator LineIterator;

    void parse_header(LineIterator& it, LineIterator const& end);
    void parse_node(LineIterator& it, LineIterator const& end);
    void parse_cpt(LineIterator& it, LineIterator const& end);

    graph_t graph_;
    std::unordered_map<std::string, vertex_type> dictionary_;
};

} // namespace io
} // namespace bn

#endif // #ifndef BNI_UTILITY_HPP
<|endoftext|>


<commit_before>/*
 * $Id: query.cc,v 2.13 2005/10/20 11:24:12 martin Exp $
 * Copyright (c) 2004, 2005, Voidsoft AB
 */

#include "query.hh"

Query::Query(TDSPP* tds)
    : TDS(tds), endoffile(false) {
    rows = new Rows();
}

Query::~Query() {
    delete rows;
}

void Query::init(void) {
}

void Query::execute(void) {
    if (ct_command(TDS->cmd, CS_LANG_CMD,
                   (CS_CHAR*)command.c_str(), CS_NULLTERM,
                   CS_UNUSED) != CS_SUCCEED)
        throw TDSPP::Exception("Query::execute: ct_command() failed");
    if (ct_send(TDS->cmd) != CS_SUCCEED) throw TDSPP::Exception("Query::execute: ct_send() failed");

    getresults();
    first();
}

void Query::getrc(void) {
    if (ct_res_info(TDS->cmd, CS_ROW_COUNT,
                    &rowcount, CS_UNUSED, NULL) != CS_SUCCEED)
        throw TDSPP::Exception("Query::getrc: ct_res_info() failed");
}

void Query::addrow(void) {
    Rows::FieldList fl;
    rows->currentrow = rows->rows.size();
    rows->rows.push_back(fl);
    for (int i=0; i < fieldcount; i ++) {
        if (!addfield()) {
            rows->rows.pop_back();
            break;
        }
    }
}

bool Query::addfield(void) {
    CS_DATAFMT datafmt;

    if (ct_describe(TDS->cmd,
                    rows->rows[rows->currentrow].size()+1, &datafmt)
        != CS_SUCCEED) {
        throw TDSPP::Exception("Query::addfield: ct_describe() failed");
    }

    /** DATETYPE is reported as 8 bytes from server,
     *  but becomes 32 when converted. Adjusting for that.
     */
    if (datafmt.maxlength < 32) datafmt.maxlength = 32;

    //if (datafmt.format == CS_FMT_UNUSED) return false;
    datafmt.format    = CS_FMT_NULLTERM;
    datafmt.datatype  = CS_CHAR_TYPE;
    if (datafmt.maxlength>1024) datafmt.maxlength = 1024;

    Field* f = new Field(datafmt.name, datafmt.maxlength);
    CS_INT datalength;
    CS_SMALLINT ind;

    if (ct_bind(TDS->cmd,
                rows->rows[rows->currentrow].size()+1,
                &datafmt,
                f->data,
                &datalength,
                &ind) != CS_SUCCEED) {
        delete f;
        throw TDSPP::Exception("Query::addfield: ct_bind() failed");
    }
    rows->rows[rows->currentrow].push_back(f);
    return true;
}

void Query::getresults(void) {

    CS_RETCODE ret;
    CS_RETCODE results_ret;
    CS_INT result_type;
    CS_INT count;
    while ((results_ret = ct_results(TDS->cmd, &result_type)) == CS_SUCCEED) {
        switch ((int) result_type) {
        case CS_CMD_SUCCEED:
            getrc();
            break;
        case CS_CMD_DONE:
            getrc();
            break;
        case CS_CMD_FAIL:
            throw TDSPP::Exception("Query::getresults: ct_results() failed.");
        case CS_ROW_RESULT:
            if (ct_res_info(TDS->cmd,
                            CS_NUMDATA,
                            &fieldcount,
                            CS_UNUSED,
                            NULL) != CS_SUCCEED)
                throw TDSPP::Exception("Query::getresults: ct_res_info() failed");
            rows->clear();
            do {
                addrow();
                ret = ct_fetch(TDS->cmd,
                               CS_UNUSED,
                               CS_UNUSED,
                               CS_UNUSED,
                               &count);
            } while (ret == CS_SUCCEED);

            switch ((int) ret) {
            case CS_END_DATA: {
                // Delete unused fields in extra row.
                Rows::FIte i;
                for (i = rows->rows.back().begin(); i != rows->rows.back().end(); ++i) {
                    delete (*i);
                }
                rows->rows.pop_back();
                break;
	    }
            case CS_ROW_FAIL:
                throw TDSPP::Exception("Query::getresults: ct_fetch() returned CS_ROW_FAIL.");
            case CS_FAIL:
                throw TDSPP::Exception("Query::getresults: ct_fetch() returned CS_FAIL.");
            default:
                throw TDSPP::Exception("Query::getresults: ct_fetch() unexpected return.");
            } // switch

            rows->currentrow = 0;
            rowcount = rows->rows.size();
            return;
        case CS_COMPUTE_RESULT:
            throw TDSPP::Exception("Query::getresults: ct_results() unexpected CS_COMPUTE_RESULT.");
        default:
            throw TDSPP::Exception("Query::getresults: ct_results() unexpected result_type.");
        } // switch
    } // while

    switch ((int) results_ret) {
    case CS_END_RESULTS:
        break;
    case CS_FAIL:
        throw TDSPP::Exception("Query::getresults: ct_results() failed.");
    default:
        throw TDSPP::Exception("Query::getresults: ct_results() unexpected return.");
    } // switch
}

void Query::next(void) {
    rows->currentrow++;
    if (rows->currentrow >= (int)rows->rows.size()) endoffile = true;
}

Field* Query::fields(int i) {
    return rows->rows[rows->currentrow][i];
}

Field* Query::fields(string s) {
    for (unsigned int i=0; i < rows->rows[rows->currentrow].size(); i++) {
        if (rows->rows[rows->currentrow][i]->colname == s) {
            return rows->rows[rows->currentrow][i];
        }
    }
    return 0;
}

void Query::first(void) {
    rows->currentrow = 0;
    if (rows->rows.size() == 0) {
        endoffile = true;
    } else {
        endoffile = false;
    }

}

bool Query::eof() {
    return endoffile;
}

string Query::operator[] (const char *s) {
    return fields(s)->tostr();
}

string Query::operator[] (string s) {
    return fields(s)->tostr();
}
<commit_msg>Not return while ct_results == CS_SUCCESS<commit_after>/*
 * $Id: query.cc,v 2.13 2005/10/20 11:24:12 martin Exp $
 * Copyright (c) 2004, 2005, Voidsoft AB
 */

#include "query.hh"

Query::Query(TDSPP* tds)
    : TDS(tds), endoffile(false) {
    rows = new Rows();
}

Query::~Query() {
    delete rows;
}

void Query::init(void) {
}

void Query::execute(void) {
    if (ct_command(TDS->cmd, CS_LANG_CMD,
                   (CS_CHAR*)command.c_str(), CS_NULLTERM,
                   CS_UNUSED) != CS_SUCCEED)
        throw TDSPP::Exception("Query::execute: ct_command() failed");
    if (ct_send(TDS->cmd) != CS_SUCCEED) throw TDSPP::Exception("Query::execute: ct_send() failed");

    getresults();
    first();
}

void Query::getrc(void) {
    if (ct_res_info(TDS->cmd, CS_ROW_COUNT,
                    &rowcount, CS_UNUSED, NULL) != CS_SUCCEED)
        throw TDSPP::Exception("Query::getrc: ct_res_info() failed");
}

void Query::addrow(void) {
    Rows::FieldList fl;
    rows->currentrow = rows->rows.size();
    rows->rows.push_back(fl);
    for (int i=0; i < fieldcount; i ++) {
        if (!addfield()) {
            rows->rows.pop_back();
            break;
        }
    }
}

bool Query::addfield(void) {
    CS_DATAFMT datafmt;

    if (ct_describe(TDS->cmd,
                    rows->rows[rows->currentrow].size()+1, &datafmt)
        != CS_SUCCEED) {
        throw TDSPP::Exception("Query::addfield: ct_describe() failed");
    }

    /** DATETYPE is reported as 8 bytes from server,
     *  but becomes 32 when converted. Adjusting for that.
     */
    if (datafmt.maxlength < 32) datafmt.maxlength = 32;

    //if (datafmt.format == CS_FMT_UNUSED) return false;
    datafmt.format    = CS_FMT_NULLTERM;
    datafmt.datatype  = CS_CHAR_TYPE;
    if (datafmt.maxlength>1024) datafmt.maxlength = 1024;

    Field* f = new Field(datafmt.name, datafmt.maxlength);
    CS_INT datalength;
    CS_SMALLINT ind;

    if (ct_bind(TDS->cmd,
                rows->rows[rows->currentrow].size()+1,
                &datafmt,
                f->data,
                &datalength,
                &ind) != CS_SUCCEED) {
        delete f;
        throw TDSPP::Exception("Query::addfield: ct_bind() failed");
    }
    rows->rows[rows->currentrow].push_back(f);
    return true;
}

void Query::getresults(void) {

    CS_RETCODE ret;
    CS_RETCODE results_ret;
    CS_INT result_type;
    CS_INT count;
    while ((results_ret = ct_results(TDS->cmd, &result_type)) == CS_SUCCEED) {
        switch ((int) result_type) {
        case CS_CMD_SUCCEED:
            getrc();
            break;
        case CS_CMD_DONE:
            getrc();
            break;
        case CS_CMD_FAIL:
            throw TDSPP::Exception("Query::getresults: ct_results() failed.");
        case CS_ROW_RESULT:
            if (ct_res_info(TDS->cmd,
                            CS_NUMDATA,
                            &fieldcount,
                            CS_UNUSED,
                            NULL) != CS_SUCCEED)
                throw TDSPP::Exception("Query::getresults: ct_res_info() failed");
            rows->clear();
            do {
                addrow();
                ret = ct_fetch(TDS->cmd,
                               CS_UNUSED,
                               CS_UNUSED,
                               CS_UNUSED,
                               &count);
            } while (ret == CS_SUCCEED);

            switch ((int) ret) {
            case CS_END_DATA: {
                // Delete unused fields in extra row.
                Rows::FIte i;
                for (i = rows->rows.back().begin(); i != rows->rows.back().end(); ++i) {
                    delete (*i);
                }
                rows->rows.pop_back();
                break;
	    }
            case CS_ROW_FAIL:
                throw TDSPP::Exception("Query::getresults: ct_fetch() returned CS_ROW_FAIL.");
            case CS_FAIL:
                throw TDSPP::Exception("Query::getresults: ct_fetch() returned CS_FAIL.");
            default:
                throw TDSPP::Exception("Query::getresults: ct_fetch() unexpected return.");
            } // switch

            rows->currentrow = 0;
            rowcount = rows->rows.size();
            break;
        case CS_COMPUTE_RESULT:
            throw TDSPP::Exception("Query::getresults: ct_results() unexpected CS_COMPUTE_RESULT.");
        default:
            throw TDSPP::Exception("Query::getresults: ct_results() unexpected result_type.");
        } // switch
    } // while

    switch ((int) results_ret) {
    case CS_END_RESULTS:
        break;
    case CS_FAIL:
        throw TDSPP::Exception("Query::getresults: ct_results() failed.");
    default:
        throw TDSPP::Exception("Query::getresults: ct_results() unexpected return.");
    } // switch
}

void Query::next(void) {
    rows->currentrow++;
    if (rows->currentrow >= (int)rows->rows.size()) endoffile = true;
}

Field* Query::fields(int i) {
    return rows->rows[rows->currentrow][i];
}

Field* Query::fields(string s) {
    for (unsigned int i=0; i < rows->rows[rows->currentrow].size(); i++) {
        if (rows->rows[rows->currentrow][i]->colname == s) {
            return rows->rows[rows->currentrow][i];
        }
    }
    return 0;
}

void Query::first(void) {
    rows->currentrow = 0;
    if (rows->rows.size() == 0) {
        endoffile = true;
    } else {
        endoffile = false;
    }

}

bool Query::eof() {
    return endoffile;
}

string Query::operator[] (const char *s) {
    return fields(s)->tostr();
}

string Query::operator[] (string s) {
    return fields(s)->tostr();
}
<|endoftext|>


<commit_before>#ifndef linux_get_thread_area_hxx_
#define linux_get_thread_area_hxx_

#include "c/EFAULT.h"
#include "c/EINVAL.h"
#include "c/SYS_get_thread_area.h"
#include "c/struct-user_desc.h"
#include "c/_c_syscall1.h"

#include "linux/Result.hxx"

namespace linux {

static inline
auto
get_thread_area(struct user_desc* u_info) noexcept
{
    enum Error
    {
        // `u_info` is an invalid pointer.
        EFAULT = EFAULT,

        // `u_info->entry_number` is out of bounds.
        EINVAL = EINVAL,
    };

    return Result<void, Error>(_c_syscall1(SYS_get_thread_area, u_info));
}

} // namespace linux

#endif
<commit_msg>get_thread_area: EFAULT refinement<commit_after>#ifndef linux_get_thread_area_hxx_
#define linux_get_thread_area_hxx_

#include "c/EFAULT.h"
#include "c/EINVAL.h"
#include "c/SYS_get_thread_area.h"
#include "c/struct-user_desc.h"
#include "c/_c_syscall1.h"

#include "linux/Result.hxx"

namespace linux {

static inline
auto
get_thread_area(struct user_desc* u_info) noexcept
{
    enum Error
    {
        // `u_info` is an invalid pointer.
        EFAULT = EFAULT,

        // `u_info->entry_number` is out of bounds.
        EINVAL = EINVAL,
    };

    return Result<void, Error>(_c_syscall1(SYS_get_thread_area, u_info));
}

static inline
auto
get_thread_area(struct user_desc& u_info) noexcept
{
    enum Error
    {
        // EFAULT
        EINVAL = EINVAL,
    };

    return Result<void, Error>(_c_syscall1(SYS_get_thread_area, &u_info));
}

} // namespace linux

#endif
<|endoftext|>


<commit_before><commit_msg>cl2 cores - info<commit_after><|endoftext|>


<commit_before>#ifndef SRC_ONLINE_AROW_HPP_
#define SRC_ONLINE_AROW_HPP_

#include <Eigen/Core>

class AROW {
private :
  const int kDim;
  const double kR;

private :
  Eigen::MatrixXd _sigma;
  Eigen::VectorXd _mu;

public :
  AROW(const int dim, const double r) : kDim(dim), kR(r) {
    static_assert(std::numeric_limits<decltype(dim)>::max() > 0, "Dimension Error. (Dimension > 0)");
    static_assert(std::numeric_limits<decltype(r)>::max() > 0, "Hyper Parameter Error. (r > 0)");

    _sigma = Eigen::MatrixXd::Identity(kDim, kDim);
    _mu = Eigen::VectorXd::Zero(kDim);
  }

  virtual ~AROW() { }

  double suffer_loss(const double margin, const int label) const {
    return margin * label;
  }

  double calculate_margin(const Eigen::VectorXd& x) const {
    return _mu.dot(x);
  }

  double calculate_confidence(const Eigen::VectorXd& x) const {
    return x.transpose() * _sigma * x;
  }

  void update(const Eigen::VectorXd& feature, const int label) {
    const auto margin = calculate_margin(feature);
    const auto confidence = calculate_confidence(feature);
    const auto beta = 1.0 / (confidence + kR);
    const auto alpha = std::max(0.0, 1.0 - label * feature.transpose() * _mu) * beta;

    if (suffer_loss(margin, label) < 1.0) {
      _mu.noalias() += alpha * _sigma * label * feature;
      _sigma -= beta * _sigma * feature * feature.transpose() * _sigma;
    }
  }

  int predict(Eigen::VectorXd& x) const {
    return calculate_margin(x) > 0.0 ? 1 : -1;
  }

};

#endif //SkRC_ONLINE_AROW_HPP_
<commit_msg>Eigen/Denseをinclude<commit_after>#ifndef SRC_ONLINE_AROW_HPP_
#define SRC_ONLINE_AROW_HPP_

#include <Eigen/Dense>

class AROW {
private :
  const int kDim;
  const double kR;

private :
  Eigen::MatrixXd _sigma;
  Eigen::VectorXd _mu;

public :
  AROW(const int dim, const double r) : kDim(dim), kR(r) {
    static_assert(std::numeric_limits<decltype(dim)>::max() > 0, "Dimension Error. (Dimension > 0)");
    static_assert(std::numeric_limits<decltype(r)>::max() > 0, "Hyper Parameter Error. (r > 0)");

    _sigma = Eigen::MatrixXd::Identity(kDim, kDim);
    _mu = Eigen::VectorXd::Zero(kDim);
  }

  virtual ~AROW() { }

  double suffer_loss(const double margin, const int label) const {
    return margin * label;
  }

  double calculate_margin(const Eigen::VectorXd& x) const {
    return _mu.dot(x);
  }

  double calculate_confidence(const Eigen::VectorXd& x) const {
    return x.transpose() * _sigma * x;
  }

  void update(const Eigen::VectorXd& feature, const int label) {
    const auto margin = calculate_margin(feature);
    const auto confidence = calculate_confidence(feature);
    const auto beta = 1.0 / (confidence + kR);
    const auto alpha = std::max(0.0, 1.0 - label * feature.transpose() * _mu) * beta;

    if (suffer_loss(margin, label) < 1.0) {
      _mu.noalias() += alpha * _sigma * label * feature;
      _sigma -= beta * _sigma * feature * feature.transpose() * _sigma;
    }
  }

  int predict(Eigen::VectorXd& x) const {
    return calculate_margin(x) > 0.0 ? 1 : -1;
  }

};

#endif //SkRC_ONLINE_AROW_HPP_
<|endoftext|>


<commit_before>#include "selectors.hh"

#include <boost/regex.hpp>
#include <algorithm>

namespace Kakoune
{

static bool is_eol(char c)
{
    return c == '\n';
}

static bool is_blank(char c)
{
    return c == ' ' or c == '\t';
}

static bool is_word(char c)
{
    if (c >= '0' and c <= '9')
        return true;
    if (c >= 'a' and c <= 'z')
        return true;
    if (c >= 'A' and c <= 'Z')
        return true;
    if (c == '_')
        return true;
    return false;
}

static bool is_punctuation(char c)
{
    return not (is_word(c) or is_blank(c) or is_eol(c));
}

enum class CharCategories
{
    Blank,
    EndOfLine,
    Word,
    Punctuation,
};

template<bool punctuation_is_not_word = true>
static CharCategories categorize(char c)
{
    if (is_word(c))
        return CharCategories::Word;
    if (is_eol(c))
        return CharCategories::EndOfLine;
    if (is_blank(c))
        return CharCategories::Blank;
    return punctuation_is_not_word ? CharCategories::Punctuation
                                   : CharCategories::Word;
}

template<typename T>
bool skip_while(BufferIterator& it, T condition)
{
    while (not it.is_end() and condition(*it))
        ++it;
    return condition(*it);
}

template<typename T>
bool skip_while_reverse(BufferIterator& it, T condition)
{
    while (not it.is_begin() and condition(*it))
        --it;
    return condition(*it);
}

Selection select_to_next_word(const BufferIterator& cursor)
{
    BufferIterator begin = cursor;
    if (categorize(*begin) != categorize(*(begin+1)))
        ++begin;

    skip_while(begin, is_eol);

    BufferIterator end = begin+1;

    if (is_punctuation(*begin))
        skip_while(end, is_punctuation);
    else if (is_word(*begin))
        skip_while(end, is_word);

    bool with_end = skip_while(end, is_blank);

    return Selection(begin, with_end ? end : end-1);
}

Selection select_to_next_word_end(const BufferIterator& cursor)
{
    BufferIterator begin = cursor;
    if (categorize(*begin) != categorize(*(begin+1)))
        ++begin;

    skip_while(begin, is_eol);
    BufferIterator end = begin;
    skip_while(end, is_blank);

    bool with_end = false;
    if (is_punctuation(*end))
        with_end = skip_while(end, is_punctuation);
    else if (is_word(*end))
        with_end = skip_while(end, is_word);

    return Selection(begin, with_end ? end : end-1);
}

Selection select_to_previous_word(const BufferIterator& cursor)
{
    BufferIterator begin = cursor;

    if (categorize(*begin) != categorize(*(begin-1)))
        --begin;

    skip_while_reverse(begin, is_eol);
    BufferIterator end = begin;
    skip_while_reverse(end, is_blank);

    bool with_end = false;
    if (is_punctuation(*end))
        with_end = skip_while_reverse(end, is_punctuation);
    else if (is_word(*end))
        with_end = skip_while_reverse(end, is_word);

    return Selection(begin, with_end ? end : end+1);
}

Selection select_to_next_WORD(const BufferIterator& cursor)
{
    BufferIterator begin = cursor;
    if (categorize<false>(*begin) != categorize<false>(*(begin+1)))
        ++begin;

    skip_while(begin, is_eol);

    BufferIterator end = begin+1;

    skip_while(end, [] (char c) { return !is_blank(c) and !is_eol(c); });
    bool with_end = skip_while(end, is_blank);

    return Selection(begin, with_end ? end : end-1);
}

Selection select_to_next_WORD_end(const BufferIterator& cursor)
{
    BufferIterator begin = cursor;
    if (categorize<false>(*begin) != categorize<false>(*(begin+1)))
        ++begin;

    skip_while(begin, is_eol);

    BufferIterator end = begin+1;

    skip_while(end, is_blank);
    bool with_end = skip_while(end, [] (char c) { return !is_blank(c)
                                                     and !is_eol(c); });

    return Selection(begin, with_end ? end : end-1);
}

Selection select_to_previous_WORD(const BufferIterator& cursor)
{
    BufferIterator begin = cursor;
    if (categorize<false>(*begin) != categorize<false>(*(begin-1)))
        --begin;

    skip_while_reverse(begin, is_eol);
    BufferIterator end = begin;
    skip_while_reverse(end, is_blank);
    bool with_end = skip_while_reverse(end, [] (char c) { return !is_blank(c)
                                                             and !is_eol(c); });

    return Selection(begin, with_end ? end : end+1);
}

Selection select_line(const BufferIterator& cursor)
{
    BufferIterator first = cursor;
    if (*first == '\n' and not first.is_end())
        ++first;

    while (not first.is_begin() and *(first - 1) != '\n')
        --first;

    BufferIterator last = first;
    while (not (last + 1).is_end() and *last != '\n')
        ++last;
    return Selection(first, last);
}

Selection select_matching(const BufferIterator& cursor)
{
    std::vector<char> matching_pairs = { '(', ')', '{', '}', '[', ']', '<', '>' };
    BufferIterator it = cursor;
    std::vector<char>::iterator match = matching_pairs.end();
    while (not is_eol(*it))
    {
        match = std::find(matching_pairs.begin(), matching_pairs.end(), *it);
        if (match != matching_pairs.end())
            break;
        ++it;
    }
    if (match == matching_pairs.end())
        return Selection(cursor, cursor);

    BufferIterator begin = it;

    if (((match - matching_pairs.begin()) % 2) == 0)
    {
        int level = 0;
        const char opening = *match;
        const char closing = *(match+1);
        while (not it.is_end())
        {
            if (*it == opening)
                ++level;
            else if (*it == closing and --level == 0)
                return Selection(begin, it);

            ++it;
        }
    }
    else
    {
        int level = 0;
        const char opening = *(match-1);
        const char closing = *match;
        while (not it.is_begin())
        {
            if (*it == closing)
                ++level;
            else if (*it == opening and --level == 0)
                return Selection(begin, it);
            --it;
        }
    }
    return Selection(cursor, cursor);
}

Selection select_to(const BufferIterator& cursor, char c, int count, bool inclusive)
{
    BufferIterator end = cursor;
    do
    {
        ++end;
        skip_while(end, [c](char cur) { return not is_eol(cur) and cur != c; });
        if (end.is_end() or is_eol(*end))
            return Selection(cursor, cursor);
    }
    while (--count > 0);

    return Selection(cursor, inclusive ? end : end-1);
}

Selection select_to_reverse(const BufferIterator& cursor, char c, int count, bool inclusive)
{
    BufferIterator end = cursor;
    do
    {
        --end;
        skip_while_reverse(end, [c](char cur) { return not is_eol(cur) and cur != c; });
        if (end.is_begin() or is_eol(*end))
            return Selection(cursor, cursor);
    }
    while (--count > 0);

    return Selection(cursor, inclusive ? end : end+1);
}

Selection select_to_eol(const BufferIterator& cursor)
{
    BufferIterator end = cursor + 1;
    skip_while(end, [](char cur) { return not is_eol(cur); });
    return Selection(cursor, end-1);
}

Selection select_to_eol_reverse(const BufferIterator& cursor)
{
    BufferIterator end = cursor - 1;
    skip_while_reverse(end, [](char cur) { return not is_eol(cur); });
    return Selection(cursor, end.is_begin() ? end : end+1);
}

SelectionList select_whole_lines(const Selection& selection)
{
     BufferIterator first = selection.first();
     BufferIterator last =  selection.last();
     BufferIterator& to_line_start = first <= last ? first : last;
     BufferIterator& to_line_end = first <= last ? last : first;

     --to_line_start;
     skip_while_reverse(to_line_start, [](char cur) { return not is_eol(cur); });
     ++to_line_start;

     skip_while(to_line_end, [](char cur) { return not is_eol(cur); });

     SelectionList result;
     result.push_back(Selection(first, last));
     return result;
}

Selection select_next_match(const BufferIterator& cursor,
                            const std::string& regex)
{
    boost::regex ex(regex);

    BufferIterator begin = cursor;
    BufferIterator end = cursor;
    Selection::CaptureList captures;

    try
    {
        boost::match_results<BufferIterator> matches;

        if (boost::regex_search(cursor, cursor.buffer().end(), matches,
                                ex))
        {
            begin = matches[0].first;
            end   = matches[0].second;
            std::copy(matches.begin(), matches.end(),
                      std::back_inserter(captures));
        }
        else if (boost::regex_search(cursor.buffer().begin(), cursor, matches,
                                     ex))
        {
            begin = matches[0].first;
            end   = matches[0].second;
            std::copy(matches.begin(), matches.end(),
                      std::back_inserter(captures));
        }
    }
    catch (boost::regex_error& err)
    {
        throw runtime_error("regex error");
    }

    if (begin == end)
        ++end;

    return Selection(begin, end - 1, std::move(captures));
}

typedef boost::regex_iterator<BufferIterator> RegexIterator;

SelectionList select_all_matches(const Selection& selection,
                                 const std::string& regex)
{
    boost::regex ex(regex);
    RegexIterator re_it(selection.begin(), selection.end(), ex);
    RegexIterator re_end;

    SelectionList result;
    for (; re_it != re_end; ++re_it)
    {
        BufferIterator begin = (*re_it)[0].first;
        BufferIterator end   = (*re_it)[0].second;

        Selection::CaptureList captures(re_it->begin(), re_it->end());

        result.push_back(Selection(begin, begin == end ? end : end-1,
                                   std::move(captures)));
    }
    return result;
}

SelectionList split_selection(const Selection& selection,
                              const std::string& separator_regex)
{
    boost::regex ex(separator_regex);
    RegexIterator re_it(selection.begin(), selection.end(), ex,
                        boost::regex_constants::match_nosubs);
    RegexIterator re_end;

    SelectionList result;
    BufferIterator begin = selection.begin();
    for (; re_it != re_end; ++re_it)
    {
        BufferIterator end = (*re_it)[0].first;

        result.push_back(Selection(begin, (begin == end) ? end : end-1));
        begin = (*re_it)[0].second;
    }
    result.push_back(Selection(begin, selection.last()));
    return result;
}

}
<commit_msg>Selectors: fix select_line on the last line<commit_after>#include "selectors.hh"

#include <boost/regex.hpp>
#include <algorithm>

namespace Kakoune
{

static bool is_eol(char c)
{
    return c == '\n';
}

static bool is_blank(char c)
{
    return c == ' ' or c == '\t';
}

static bool is_word(char c)
{
    if (c >= '0' and c <= '9')
        return true;
    if (c >= 'a' and c <= 'z')
        return true;
    if (c >= 'A' and c <= 'Z')
        return true;
    if (c == '_')
        return true;
    return false;
}

static bool is_punctuation(char c)
{
    return not (is_word(c) or is_blank(c) or is_eol(c));
}

enum class CharCategories
{
    Blank,
    EndOfLine,
    Word,
    Punctuation,
};

template<bool punctuation_is_not_word = true>
static CharCategories categorize(char c)
{
    if (is_word(c))
        return CharCategories::Word;
    if (is_eol(c))
        return CharCategories::EndOfLine;
    if (is_blank(c))
        return CharCategories::Blank;
    return punctuation_is_not_word ? CharCategories::Punctuation
                                   : CharCategories::Word;
}

template<typename T>
bool skip_while(BufferIterator& it, T condition)
{
    while (not it.is_end() and condition(*it))
        ++it;
    return condition(*it);
}

template<typename T>
bool skip_while_reverse(BufferIterator& it, T condition)
{
    while (not it.is_begin() and condition(*it))
        --it;
    return condition(*it);
}

Selection select_to_next_word(const BufferIterator& cursor)
{
    BufferIterator begin = cursor;
    if (categorize(*begin) != categorize(*(begin+1)))
        ++begin;

    skip_while(begin, is_eol);

    BufferIterator end = begin+1;

    if (is_punctuation(*begin))
        skip_while(end, is_punctuation);
    else if (is_word(*begin))
        skip_while(end, is_word);

    bool with_end = skip_while(end, is_blank);

    return Selection(begin, with_end ? end : end-1);
}

Selection select_to_next_word_end(const BufferIterator& cursor)
{
    BufferIterator begin = cursor;
    if (categorize(*begin) != categorize(*(begin+1)))
        ++begin;

    skip_while(begin, is_eol);
    BufferIterator end = begin;
    skip_while(end, is_blank);

    bool with_end = false;
    if (is_punctuation(*end))
        with_end = skip_while(end, is_punctuation);
    else if (is_word(*end))
        with_end = skip_while(end, is_word);

    return Selection(begin, with_end ? end : end-1);
}

Selection select_to_previous_word(const BufferIterator& cursor)
{
    BufferIterator begin = cursor;

    if (categorize(*begin) != categorize(*(begin-1)))
        --begin;

    skip_while_reverse(begin, is_eol);
    BufferIterator end = begin;
    skip_while_reverse(end, is_blank);

    bool with_end = false;
    if (is_punctuation(*end))
        with_end = skip_while_reverse(end, is_punctuation);
    else if (is_word(*end))
        with_end = skip_while_reverse(end, is_word);

    return Selection(begin, with_end ? end : end+1);
}

Selection select_to_next_WORD(const BufferIterator& cursor)
{
    BufferIterator begin = cursor;
    if (categorize<false>(*begin) != categorize<false>(*(begin+1)))
        ++begin;

    skip_while(begin, is_eol);

    BufferIterator end = begin+1;

    skip_while(end, [] (char c) { return !is_blank(c) and !is_eol(c); });
    bool with_end = skip_while(end, is_blank);

    return Selection(begin, with_end ? end : end-1);
}

Selection select_to_next_WORD_end(const BufferIterator& cursor)
{
    BufferIterator begin = cursor;
    if (categorize<false>(*begin) != categorize<false>(*(begin+1)))
        ++begin;

    skip_while(begin, is_eol);

    BufferIterator end = begin+1;

    skip_while(end, is_blank);
    bool with_end = skip_while(end, [] (char c) { return !is_blank(c)
                                                     and !is_eol(c); });

    return Selection(begin, with_end ? end : end-1);
}

Selection select_to_previous_WORD(const BufferIterator& cursor)
{
    BufferIterator begin = cursor;
    if (categorize<false>(*begin) != categorize<false>(*(begin-1)))
        --begin;

    skip_while_reverse(begin, is_eol);
    BufferIterator end = begin;
    skip_while_reverse(end, is_blank);
    bool with_end = skip_while_reverse(end, [] (char c) { return !is_blank(c)
                                                             and !is_eol(c); });

    return Selection(begin, with_end ? end : end+1);
}

Selection select_line(const BufferIterator& cursor)
{
    BufferIterator first = cursor;
    if (*first == '\n' and not (first + 1).is_end())
        ++first;

    while (not first.is_begin() and *(first - 1) != '\n')
        --first;

    BufferIterator last = first;
    while (not (last + 1).is_end() and *last != '\n')
        ++last;
    return Selection(first, last);
}

Selection select_matching(const BufferIterator& cursor)
{
    std::vector<char> matching_pairs = { '(', ')', '{', '}', '[', ']', '<', '>' };
    BufferIterator it = cursor;
    std::vector<char>::iterator match = matching_pairs.end();
    while (not is_eol(*it))
    {
        match = std::find(matching_pairs.begin(), matching_pairs.end(), *it);
        if (match != matching_pairs.end())
            break;
        ++it;
    }
    if (match == matching_pairs.end())
        return Selection(cursor, cursor);

    BufferIterator begin = it;

    if (((match - matching_pairs.begin()) % 2) == 0)
    {
        int level = 0;
        const char opening = *match;
        const char closing = *(match+1);
        while (not it.is_end())
        {
            if (*it == opening)
                ++level;
            else if (*it == closing and --level == 0)
                return Selection(begin, it);

            ++it;
        }
    }
    else
    {
        int level = 0;
        const char opening = *(match-1);
        const char closing = *match;
        while (not it.is_begin())
        {
            if (*it == closing)
                ++level;
            else if (*it == opening and --level == 0)
                return Selection(begin, it);
            --it;
        }
    }
    return Selection(cursor, cursor);
}

Selection select_to(const BufferIterator& cursor, char c, int count, bool inclusive)
{
    BufferIterator end = cursor;
    do
    {
        ++end;
        skip_while(end, [c](char cur) { return not is_eol(cur) and cur != c; });
        if (end.is_end() or is_eol(*end))
            return Selection(cursor, cursor);
    }
    while (--count > 0);

    return Selection(cursor, inclusive ? end : end-1);
}

Selection select_to_reverse(const BufferIterator& cursor, char c, int count, bool inclusive)
{
    BufferIterator end = cursor;
    do
    {
        --end;
        skip_while_reverse(end, [c](char cur) { return not is_eol(cur) and cur != c; });
        if (end.is_begin() or is_eol(*end))
            return Selection(cursor, cursor);
    }
    while (--count > 0);

    return Selection(cursor, inclusive ? end : end+1);
}

Selection select_to_eol(const BufferIterator& cursor)
{
    BufferIterator end = cursor + 1;
    skip_while(end, [](char cur) { return not is_eol(cur); });
    return Selection(cursor, end-1);
}

Selection select_to_eol_reverse(const BufferIterator& cursor)
{
    BufferIterator end = cursor - 1;
    skip_while_reverse(end, [](char cur) { return not is_eol(cur); });
    return Selection(cursor, end.is_begin() ? end : end+1);
}

SelectionList select_whole_lines(const Selection& selection)
{
     BufferIterator first = selection.first();
     BufferIterator last =  selection.last();
     BufferIterator& to_line_start = first <= last ? first : last;
     BufferIterator& to_line_end = first <= last ? last : first;

     --to_line_start;
     skip_while_reverse(to_line_start, [](char cur) { return not is_eol(cur); });
     ++to_line_start;

     skip_while(to_line_end, [](char cur) { return not is_eol(cur); });

     SelectionList result;
     result.push_back(Selection(first, last));
     return result;
}

Selection select_next_match(const BufferIterator& cursor,
                            const std::string& regex)
{
    boost::regex ex(regex);

    BufferIterator begin = cursor;
    BufferIterator end = cursor;
    Selection::CaptureList captures;

    try
    {
        boost::match_results<BufferIterator> matches;

        if (boost::regex_search(cursor, cursor.buffer().end(), matches,
                                ex))
        {
            begin = matches[0].first;
            end   = matches[0].second;
            std::copy(matches.begin(), matches.end(),
                      std::back_inserter(captures));
        }
        else if (boost::regex_search(cursor.buffer().begin(), cursor, matches,
                                     ex))
        {
            begin = matches[0].first;
            end   = matches[0].second;
            std::copy(matches.begin(), matches.end(),
                      std::back_inserter(captures));
        }
    }
    catch (boost::regex_error& err)
    {
        throw runtime_error("regex error");
    }

    if (begin == end)
        ++end;

    return Selection(begin, end - 1, std::move(captures));
}

typedef boost::regex_iterator<BufferIterator> RegexIterator;

SelectionList select_all_matches(const Selection& selection,
                                 const std::string& regex)
{
    boost::regex ex(regex);
    RegexIterator re_it(selection.begin(), selection.end(), ex);
    RegexIterator re_end;

    SelectionList result;
    for (; re_it != re_end; ++re_it)
    {
        BufferIterator begin = (*re_it)[0].first;
        BufferIterator end   = (*re_it)[0].second;

        Selection::CaptureList captures(re_it->begin(), re_it->end());

        result.push_back(Selection(begin, begin == end ? end : end-1,
                                   std::move(captures)));
    }
    return result;
}

SelectionList split_selection(const Selection& selection,
                              const std::string& separator_regex)
{
    boost::regex ex(separator_regex);
    RegexIterator re_it(selection.begin(), selection.end(), ex,
                        boost::regex_constants::match_nosubs);
    RegexIterator re_end;

    SelectionList result;
    BufferIterator begin = selection.begin();
    for (; re_it != re_end; ++re_it)
    {
        BufferIterator end = (*re_it)[0].first;

        result.push_back(Selection(begin, (begin == end) ? end : end-1));
        begin = (*re_it)[0].second;
    }
    result.push_back(Selection(begin, selection.last()));
    return result;
}

}
<|endoftext|>


<commit_before>#include <cctype>
#include <fstream>
#include <stdio.h>
#include <sstream> // ostringstream
#include "utils/logoutput.h"

#include "settings.h"
#include "settingRegistry.h"

namespace cura
{
//c++11 no longer defines M_PI, so add our own constant.
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif

SettingsBaseVirtual::SettingsBaseVirtual()
: parent(NULL)
{
}

SettingsBaseVirtual::SettingsBaseVirtual(SettingsBaseVirtual* parent)
: parent(parent)
{
}

SettingsBase::SettingsBase()
: SettingsBaseVirtual(NULL)
{
}

SettingsBase::SettingsBase(SettingsBaseVirtual* parent)
: SettingsBaseVirtual(parent)
{
}

SettingsMessenger::SettingsMessenger(SettingsBaseVirtual* parent)
: SettingsBaseVirtual(parent)
{
}

void SettingsBase::setSetting(std::string key, std::string value)
{
    if (SettingRegistry::getInstance()->settingExists(key))
    {
        setting_values[key] = value;
    }
    else
    {
        cura::logError("Warning: setting an unregistered setting %s\n", key.c_str() );
        setting_values[key] = value; // Handy when programmers are in the process of introducing a new setting
    }
}

std::string SettingsBase::getSettingString(std::string key)
{
    if (setting_values.find(key) != setting_values.end())
    {
        return setting_values[key];
    }
    if (parent)
    {
        return parent->getSettingString(key);
    }

    if (SettingRegistry::getInstance()->settingExists(key))
    {
        setting_values[key] = SettingRegistry::getInstance()->getSettingConfig(key)->getDefaultValue();
    }
    else
    {
        setting_values[key] = "";
        cura::logError("Unregistered setting %s\n", key.c_str());
    }
    return setting_values[key];
}

void SettingsMessenger::setSetting(std::string key, std::string value)
{
    parent->setSetting(key, value);
}

std::string SettingsMessenger::getSettingString(std::string key)
{
    return parent->getSettingString(key);
}

void SettingsBase::setExtruderTrainDefaults(unsigned int extruder_nr)
{
    const SettingContainer* machine_extruder_trains = SettingRegistry::getInstance()->getCategory(std::string("machine_extruder_trains"));

    if (!machine_extruder_trains)
    {
        logWarning("Error: no machine_extruder_trains category found in JSON!\n");
        return;
    }

    const SettingConfig* train = machine_extruder_trains->getChild(extruder_nr);

    if (!train)
    {
        logError("Not enough extruder trains specified in JSON: %i\n", extruder_nr);
        return;
    }

    for (const SettingConfig& setting : train->getChildren())
    {
        if (setting_values.find(setting.getKey()) == setting_values.end())
        {
            setSetting(setting.getKey(), setting.getDefaultValue());
        }
    }
}

int SettingsBaseVirtual::getSettingAsIndex(std::string key)
{
    std::string value = getSettingString(key);
    return atoi(value.c_str());
}

int SettingsBaseVirtual::getSettingAsCount(std::string key)
{
    std::string value = getSettingString(key);
    return atoi(value.c_str());
}

int SettingsBaseVirtual::getSettingInMicrons(std::string key)
{
    std::string value = getSettingString(key);
    return atof(value.c_str()) * 1000.0;
}

double SettingsBaseVirtual::getSettingInAngleRadians(std::string key)
{
    std::string value = getSettingString(key);
    return atof(value.c_str()) / 180.0 * M_PI;
}

bool SettingsBaseVirtual::getSettingBoolean(std::string key)
{
    std::string value = getSettingString(key);
    if (value == "on")
        return true;
    if (value == "yes")
        return true;
    if (value == "true" or value == "True") //Python uses "True"
        return true;
    int num = atoi(value.c_str());
    return num != 0;
}

double SettingsBaseVirtual::getSettingInDegreeCelsius(std::string key)
{
    std::string value = getSettingString(key);
    return atof(value.c_str());
}

double SettingsBaseVirtual::getSettingInMillimetersPerSecond(std::string key)
{
    std::string value = getSettingString(key);
    return std::max(1.0, atof(value.c_str()));
}

double SettingsBaseVirtual::getSettingInCubicMillimeters(std::string key)
{
    std::string value = getSettingString(key);
    return std::max(0.0, atof(value.c_str()));
}

double SettingsBaseVirtual::getSettingInPercentage(std::string key)
{
    std::string value = getSettingString(key);
    return std::max(0.0, atof(value.c_str()));
}

double SettingsBaseVirtual::getSettingInSeconds(std::string key)
{
    std::string value = getSettingString(key);
    return std::max(0.0, atof(value.c_str()));
}

FlowTempGraph SettingsBaseVirtual::getSettingAsFlowTempGraph(std::string key)
{
    FlowTempGraph ret;
    const char* c_str = getSettingString(key).c_str();
    char const* char_p = c_str;
    while (*char_p != '[')
    {
        char_p++;
    }
    char_p++; // skip the '['
    for (; *char_p != '\0'; char_p++)
    {
        while (*char_p != '[')
        {
            char_p++;
        }
        char_p++; // skip the '['
        char* end;
        double first = strtod(char_p, &end);
        char_p = end;
        while (*char_p != ',')
        {
            char_p++;
        }
        char_p++; // skip the ','
        double second = strtod(char_p, &end);
        char_p = end;
        while (*char_p != ']')
        {
            char_p++;
        }
        char_p++; // skip the ']'
        ret.data.emplace_back(first, second);
        if (*char_p == ']')
        {
            break;
        }
    }
    return ret;
}

EGCodeFlavor SettingsBaseVirtual::getSettingAsGCodeFlavor(std::string key)
{
    std::string value = getSettingString(key);
    if (value == "RepRap")
        return EGCodeFlavor::REPRAP;
    else if (value == "UltiGCode")
        return EGCodeFlavor::ULTIGCODE;
    else if (value == "Makerbot")
        return EGCodeFlavor::MAKERBOT;
    else if (value == "BFB")
        return EGCodeFlavor::BFB;
    else if (value == "MACH3")
        return EGCodeFlavor::MACH3;
    else if (value == "RepRap (Volumatric)")
        return EGCodeFlavor::REPRAP_VOLUMATRIC;
    return EGCodeFlavor::REPRAP;
}

EFillMethod SettingsBaseVirtual::getSettingAsFillMethod(std::string key)
{
    std::string value = getSettingString(key);
    if (value == "lines")
        return EFillMethod::LINES;
    if (value == "grid")
        return EFillMethod::GRID;
    if (value == "triangles")
        return EFillMethod::TRIANGLES;
    if (value == "concentric")
        return EFillMethod::CONCENTRIC;
    if (value == "zigzag")
        return EFillMethod::ZIG_ZAG;
    return EFillMethod::NONE;
}

EPlatformAdhesion SettingsBaseVirtual::getSettingAsPlatformAdhesion(std::string key)
{
    std::string value = getSettingString(key);
    if (value == "brim")
        return EPlatformAdhesion::BRIM;
    if (value == "raft")
        return EPlatformAdhesion::RAFT;
    return EPlatformAdhesion::SKIRT;
}

ESupportType SettingsBaseVirtual::getSettingAsSupportType(std::string key)
{
    std::string value = getSettingString(key);
    if (value == "everywhere")
        return ESupportType::EVERYWHERE;
    if (value == "buildplate")
        return ESupportType::PLATFORM_ONLY;
    return ESupportType::NONE;
}

EZSeamType SettingsBaseVirtual::getSettingAsZSeamType(std::string key)
{
    std::string value = getSettingString(key);
    if (value == "random")
        return EZSeamType::RANDOM;
    if (value == "shortest")
        return EZSeamType::SHORTEST;
    if (value == "back")
        return EZSeamType::BACK;
    return EZSeamType::SHORTEST;
}

ESurfaceMode SettingsBaseVirtual::getSettingAsSurfaceMode(std::string key)
{
    std::string value = getSettingString(key);
    if (value == "normal")
        return ESurfaceMode::NORMAL;
    if (value == "surface")
        return ESurfaceMode::SURFACE;
    if (value == "both")
        return ESurfaceMode::BOTH;
    return ESurfaceMode::NORMAL;
}

FillPerimeterGapMode SettingsBaseVirtual::getSettingAsFillPerimeterGapMode(std::string key)
{
    std::string value = getSettingString(key);
    if (value == "nowhere")
    {
        return FillPerimeterGapMode::NOWHERE;
    }
    if (value == "everywhere")
    {
        return FillPerimeterGapMode::EVERYWHERE;
    }
    if (value == "skin")
    {
        return FillPerimeterGapMode::SKIN;
    }
    return FillPerimeterGapMode::NOWHERE;
}

}//namespace cura
<commit_msg>no more error when no extruder trains are present<commit_after>#include <cctype>
#include <fstream>
#include <stdio.h>
#include <sstream> // ostringstream
#include "utils/logoutput.h"

#include "settings.h"
#include "settingRegistry.h"

namespace cura
{
//c++11 no longer defines M_PI, so add our own constant.
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif

SettingsBaseVirtual::SettingsBaseVirtual()
: parent(NULL)
{
}

SettingsBaseVirtual::SettingsBaseVirtual(SettingsBaseVirtual* parent)
: parent(parent)
{
}

SettingsBase::SettingsBase()
: SettingsBaseVirtual(NULL)
{
}

SettingsBase::SettingsBase(SettingsBaseVirtual* parent)
: SettingsBaseVirtual(parent)
{
}

SettingsMessenger::SettingsMessenger(SettingsBaseVirtual* parent)
: SettingsBaseVirtual(parent)
{
}

void SettingsBase::setSetting(std::string key, std::string value)
{
    if (SettingRegistry::getInstance()->settingExists(key))
    {
        setting_values[key] = value;
    }
    else
    {
        cura::logError("Warning: setting an unregistered setting %s\n", key.c_str() );
        setting_values[key] = value; // Handy when programmers are in the process of introducing a new setting
    }
}

std::string SettingsBase::getSettingString(std::string key)
{
    if (setting_values.find(key) != setting_values.end())
    {
        return setting_values[key];
    }
    if (parent)
    {
        return parent->getSettingString(key);
    }

    if (SettingRegistry::getInstance()->settingExists(key))
    {
        setting_values[key] = SettingRegistry::getInstance()->getSettingConfig(key)->getDefaultValue();
    }
    else
    {
        setting_values[key] = "";
        cura::logError("Unregistered setting %s\n", key.c_str());
    }
    return setting_values[key];
}

void SettingsMessenger::setSetting(std::string key, std::string value)
{
    parent->setSetting(key, value);
}

std::string SettingsMessenger::getSettingString(std::string key)
{
    return parent->getSettingString(key);
}

void SettingsBase::setExtruderTrainDefaults(unsigned int extruder_nr)
{
    const SettingContainer* machine_extruder_trains = SettingRegistry::getInstance()->getCategory(std::string("machine_extruder_trains"));

    if (!machine_extruder_trains)
    {
        // no machine_extruder_trains setting present; just use defaults for each train..
        return;
    }

    const SettingConfig* train = machine_extruder_trains->getChild(extruder_nr);

    if (!train)
    {
        logError("Not enough extruder trains specified in JSON: %i\n", extruder_nr);
        return;
    }

    for (const SettingConfig& setting : train->getChildren())
    {
        if (setting_values.find(setting.getKey()) == setting_values.end())
        {
            setSetting(setting.getKey(), setting.getDefaultValue());
        }
    }
}

int SettingsBaseVirtual::getSettingAsIndex(std::string key)
{
    std::string value = getSettingString(key);
    return atoi(value.c_str());
}

int SettingsBaseVirtual::getSettingAsCount(std::string key)
{
    std::string value = getSettingString(key);
    return atoi(value.c_str());
}

int SettingsBaseVirtual::getSettingInMicrons(std::string key)
{
    std::string value = getSettingString(key);
    return atof(value.c_str()) * 1000.0;
}

double SettingsBaseVirtual::getSettingInAngleRadians(std::string key)
{
    std::string value = getSettingString(key);
    return atof(value.c_str()) / 180.0 * M_PI;
}

bool SettingsBaseVirtual::getSettingBoolean(std::string key)
{
    std::string value = getSettingString(key);
    if (value == "on")
        return true;
    if (value == "yes")
        return true;
    if (value == "true" or value == "True") //Python uses "True"
        return true;
    int num = atoi(value.c_str());
    return num != 0;
}

double SettingsBaseVirtual::getSettingInDegreeCelsius(std::string key)
{
    std::string value = getSettingString(key);
    return atof(value.c_str());
}

double SettingsBaseVirtual::getSettingInMillimetersPerSecond(std::string key)
{
    std::string value = getSettingString(key);
    return std::max(1.0, atof(value.c_str()));
}

double SettingsBaseVirtual::getSettingInCubicMillimeters(std::string key)
{
    std::string value = getSettingString(key);
    return std::max(0.0, atof(value.c_str()));
}

double SettingsBaseVirtual::getSettingInPercentage(std::string key)
{
    std::string value = getSettingString(key);
    return std::max(0.0, atof(value.c_str()));
}

double SettingsBaseVirtual::getSettingInSeconds(std::string key)
{
    std::string value = getSettingString(key);
    return std::max(0.0, atof(value.c_str()));
}

FlowTempGraph SettingsBaseVirtual::getSettingAsFlowTempGraph(std::string key)
{
    FlowTempGraph ret;
    const char* c_str = getSettingString(key).c_str();
    char const* char_p = c_str;
    while (*char_p != '[')
    {
        char_p++;
    }
    char_p++; // skip the '['
    for (; *char_p != '\0'; char_p++)
    {
        while (*char_p != '[')
        {
            char_p++;
        }
        char_p++; // skip the '['
        char* end;
        double first = strtod(char_p, &end);
        char_p = end;
        while (*char_p != ',')
        {
            char_p++;
        }
        char_p++; // skip the ','
        double second = strtod(char_p, &end);
        char_p = end;
        while (*char_p != ']')
        {
            char_p++;
        }
        char_p++; // skip the ']'
        ret.data.emplace_back(first, second);
        if (*char_p == ']')
        {
            break;
        }
    }
    return ret;
}

EGCodeFlavor SettingsBaseVirtual::getSettingAsGCodeFlavor(std::string key)
{
    std::string value = getSettingString(key);
    if (value == "RepRap")
        return EGCodeFlavor::REPRAP;
    else if (value == "UltiGCode")
        return EGCodeFlavor::ULTIGCODE;
    else if (value == "Makerbot")
        return EGCodeFlavor::MAKERBOT;
    else if (value == "BFB")
        return EGCodeFlavor::BFB;
    else if (value == "MACH3")
        return EGCodeFlavor::MACH3;
    else if (value == "RepRap (Volumatric)")
        return EGCodeFlavor::REPRAP_VOLUMATRIC;
    return EGCodeFlavor::REPRAP;
}

EFillMethod SettingsBaseVirtual::getSettingAsFillMethod(std::string key)
{
    std::string value = getSettingString(key);
    if (value == "lines")
        return EFillMethod::LINES;
    if (value == "grid")
        return EFillMethod::GRID;
    if (value == "triangles")
        return EFillMethod::TRIANGLES;
    if (value == "concentric")
        return EFillMethod::CONCENTRIC;
    if (value == "zigzag")
        return EFillMethod::ZIG_ZAG;
    return EFillMethod::NONE;
}

EPlatformAdhesion SettingsBaseVirtual::getSettingAsPlatformAdhesion(std::string key)
{
    std::string value = getSettingString(key);
    if (value == "brim")
        return EPlatformAdhesion::BRIM;
    if (value == "raft")
        return EPlatformAdhesion::RAFT;
    return EPlatformAdhesion::SKIRT;
}

ESupportType SettingsBaseVirtual::getSettingAsSupportType(std::string key)
{
    std::string value = getSettingString(key);
    if (value == "everywhere")
        return ESupportType::EVERYWHERE;
    if (value == "buildplate")
        return ESupportType::PLATFORM_ONLY;
    return ESupportType::NONE;
}

EZSeamType SettingsBaseVirtual::getSettingAsZSeamType(std::string key)
{
    std::string value = getSettingString(key);
    if (value == "random")
        return EZSeamType::RANDOM;
    if (value == "shortest")
        return EZSeamType::SHORTEST;
    if (value == "back")
        return EZSeamType::BACK;
    return EZSeamType::SHORTEST;
}

ESurfaceMode SettingsBaseVirtual::getSettingAsSurfaceMode(std::string key)
{
    std::string value = getSettingString(key);
    if (value == "normal")
        return ESurfaceMode::NORMAL;
    if (value == "surface")
        return ESurfaceMode::SURFACE;
    if (value == "both")
        return ESurfaceMode::BOTH;
    return ESurfaceMode::NORMAL;
}

FillPerimeterGapMode SettingsBaseVirtual::getSettingAsFillPerimeterGapMode(std::string key)
{
    std::string value = getSettingString(key);
    if (value == "nowhere")
    {
        return FillPerimeterGapMode::NOWHERE;
    }
    if (value == "everywhere")
    {
        return FillPerimeterGapMode::EVERYWHERE;
    }
    if (value == "skin")
    {
        return FillPerimeterGapMode::SKIN;
    }
    return FillPerimeterGapMode::NOWHERE;
}

}//namespace cura
<|endoftext|>


<commit_before>/************************************************************************
 *     File: stereo.cc
 *     Date: April 2005
 *       By: Michael Broxton and Larry Edwards
 *      For: NASA Ames Research Center, Intelligent Mechanisms Group
 * Function: Main program for the stereo pipeline
 ************************************************************************/
#include <boost/algorithm/string.hpp>
#include <boost/program_options.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/convenience.hpp>
#include <boost/filesystem/fstream.hpp>
using namespace boost;
namespace po = boost::program_options;
namespace fs = boost::filesystem;

#include <vw/Core.h>
#include <vw/Image.h>
#include <vw/FileIO.h>
#include <vw/Camera.h>
#include <vw/Cartography.h>
#include <vw/Cartography/OrthoImageView.h>
using namespace vw;
using namespace vw::camera;
using namespace vw::cartography;

#include "asp_config.h"
#include "StereoSession.h"
using namespace std;

#if defined(ASP_HAVE_PKG_ISIS) && ASP_HAVE_PKG_ISIS == 1
#include "Isis/DiskImageResourceIsis.h"
#include "Isis/StereoSessionIsis.h"
#endif

#include "HRSC/StereoSessionHRSC.h"
#include "MOC/StereoSessionMOC.h"
#include "apollo/StereoSessionApolloMetric.h"
#include "MRO/StereoSessionCTX.h"
#include "RMAX/StereoSessionRmax.h"

// Allows FileIO to correctly read/write these pixel types
namespace vw {
  template<> struct PixelFormatID<Vector3>   { static const PixelFormatEnum value = VW_PIXEL_GENERIC_3_CHANNEL; };
}

template <class ViewT, class DemViewT>
GeoReference compute_geotransform_from_camera(ImageViewBase<ViewT> const& view,
                                              boost::shared_ptr<CameraModel> camera,
                                              ImageViewBase<DemViewT> const& dem,
                                              GeoReference const& dem_georef,
                                              double scale,
                                              double &output_width, double& output_height) {

  // Adopt the datum & projection of the parent DEM.
  GeoReference geo = dem_georef;

  // Compute the longitude/latitude bounding box and the lonlat pixel scale
  float lonlat_scale;
  BBox2 image_bbox = camera_bbox(dem_georef, camera, view.impl().cols(), view.impl().rows(), lonlat_scale);
  BBox2 dem_bbox = dem_georef.lonlat_bounding_box(dem);

  // Use a bbox where both the image and the DEM have valid data.
  // Throw an error if there turns out to be no overlap.
  BBox2 bbox = image_bbox;
  bbox.crop(dem_bbox);
  if (bbox.width() == 0 || bbox.height() == 0) {
    std::cout << "Image bounding box (" << image_bbox << ") and DEM bounding box (" << dem_bbox << ") have no overlap.  Are you sure that your input files overlap?\n";
    exit(0);
  }

  float diff1 = bbox.max().x()-bbox.min().x();

  // Convert the lon/lat bounding box into the map projection.
  bbox.min() = geo.lonlat_to_point(bbox.min());
  bbox.max() = geo.lonlat_to_point(bbox.max());
  float diff2 = bbox.max().x()-bbox.min().x();

  // Convert the scale into the projected space
  double projected_space_scale = lonlat_scale * diff2 / diff1;

  // If the user has supplied a scale, we override our computed value
  // here.
  if (scale != 0) {
    projected_space_scale = scale;
  }

  // Compute the affine transform for this image.
  Matrix3x3 trans = geo.transform();

  trans(0,0) = projected_space_scale;
  trans(1,1) = -projected_space_scale;
  trans(0,2) = bbox.min().x();
  trans(1,2) = bbox.max().y();
  geo.set_transform(trans);

  // Compute the width and height of the output image so that it
  // contains the entirety of the computed bounding box.
  output_width = (bbox.max().x() - bbox.min().x()) / projected_space_scale;
  output_height = (bbox.max().y() - bbox.min().y()) / projected_space_scale;

  return geo;
}

//***********************************************************************
// MAIN
//***********************************************************************

int main(int argc, char* argv[]) {

  /*************************************/
  /* Parsing of command line arguments */
  /*************************************/

  // Boost has a nice command line parsing utility, which we use here
  // to specify the type, size, help string, etc, of the command line
  // arguments.
  int debug_level;
  unsigned cache_size;
  std::string dem_file, image_file, camera_model_file, output_file;
  std::string stereo_session_string;
  double mpp;
  double ppd;
  double missing_pixel_value;

  po::options_description visible_options("Options");
  visible_options.add_options()
    ("help,h", "Display this help message")
    ("mpp", po::value<double>(&mpp), "Specify the output resolution of the orthoimage in meters per pixel.")
    ("ppd", po::value<double>(&ppd), "Specify the output resolution of the orthoimage in pixels per degree.")
    ("missing-pixel", po::value<double>(&missing_pixel_value)->default_value(-6000), "Specify the pixel used in this DEM to denote missing data.")
    ("match-dem,m", "Match the georeferencing parameters and dimensions of the input DEM.")
    ("cache", po::value<unsigned>(&cache_size)->default_value(2048), "Cache size, in megabytes")
    ("session-type,t", po::value<std::string>(&stereo_session_string)->default_value("pinhole"), "Select the stereo session type to use for processing. [default: pinhole]")
    ("debug-level,d", po::value<int>(&debug_level)->default_value(vw::DebugMessage-1), "Set the debugging output level. (0-50+)");

  po::options_description positional_options("Positional Options");
  positional_options.add_options()
    ("dem", po::value<std::string>(&dem_file), "DEM Input File")
    ("camera-image", po::value<std::string>(&image_file), "Camera Input file")
    ("camera-model", po::value<std::string>(&camera_model_file), "Camera Model File")
    ("output-file", po::value<std::string>(&output_file), "Output filename");
  po::positional_options_description positional_options_desc;
  positional_options_desc.add("dem", 1);
  positional_options_desc.add("camera-image", 1);
  positional_options_desc.add("camera-model", 1);
  positional_options_desc.add("output-file", 1);

  po::options_description all_options;
  all_options.add(visible_options).add(positional_options);

  po::variables_map vm;
  po::store( po::command_line_parser( argc, argv ).options(all_options).positional(positional_options_desc).run(), vm );
  po::notify( vm );

  // If the command line wasn't properly formed or the user requested
  // help, we print an usage message.
  if( vm.count("help") ||
      !vm.count("dem") ||
      !vm.count("camera-image") || !vm.count("camera-model") ||
      !vm.count("output-file")) {
    std::cout << "\nUsage: orthoproject [options] <dem filename> <camera image> <camera model> <output filename>\n";
    std::cout << visible_options << std::endl;
    return 1;
  }

  // Set the Vision Workbench debug level
  set_debug_level(debug_level);
  Cache::system_cache().resize( cache_size*1024*1024 ); // Set cache to 1Gb

  // Create a fresh stereo session and query it for the camera models.
  StereoSession::register_session_type( "hrsc", &StereoSessionHRSC::construct);
  StereoSession::register_session_type( "moc", &StereoSessionMOC::construct);
  StereoSession::register_session_type( "metric", &StereoSessionApolloMetric::construct);
  StereoSession::register_session_type( "ctx", &StereoSessionCTX::construct);
  StereoSession::register_session_type( "rmax", &StereoSessionRmax::construct);
#if defined(ASP_HAVE_PKG_ISIS) && ASP_HAVE_PKG_ISIS == 1
  StereoSession::register_session_type( "isis", &StereoSessionIsis::construct);
#endif

  // Okay, here's a total hack.  We create a stereo session where both
  // of the imagers and images are the same, because we want to take
  // advantage of the stereo pipeline's ability to generate camera
  // models for various missions.  Hence, we create two identical
  // camera models, but only one is used.  The last four empty strings
  // are dummy arguments.
  StereoSession* session = StereoSession::create(stereo_session_string);
  session->initialize(image_file, image_file, camera_model_file, camera_model_file,
                      output_file, "", "","","" );
  boost::shared_ptr<camera::CameraModel> camera_model;
  camera_model = session->camera_model(image_file, camera_model_file);

  // Open the DEM
  GeoReference dem_georef;
  cartography::read_georeference(dem_georef, dem_file);

  DiskImageView<PixelGray<float> > dem_disk_image(dem_file);
  ImageViewRef<PixelMask<PixelGray<float> > > dem = pixel_cast<PixelMask<PixelGray<float> > >(dem_disk_image);

  if (vm.count("missing-pixel")) {
    std::cout << "\t--> Using " << missing_pixel_value << " as the missing data value for the DEM.\n";
    dem = create_mask(dem_disk_image, missing_pixel_value);
  }

  DiskImageView<PixelGrayA<uint8> > texture_disk_image(image_file);
  ImageViewRef<PixelGrayA<uint8> > texture_image = texture_disk_image;
  DiskImageView<PixelGrayA<float> > float_texture_disk_image(image_file);

  // ISIS cubes need to be normalized because their pixels are often
  // photometrically calibrated.
  if (stereo_session_string == "isis") {
    float lo, hi;
    isis_min_max_channel_values(float_texture_disk_image, lo, hi);
    vw_out(InfoMessage) << "Normalizing ISIS Pixel Range: [" << lo << " " << hi << "]    " << std::flush;
    texture_image = channel_cast_rescale<uint8>(normalize_retain_alpha(remove_isis_special_pixels(float_texture_disk_image, PixelGrayA<float>(lo)), lo, hi, 0, 1.0));
  }

  // Parse the scale of the output image from the command line
  // arguments.  This value can be set either in meters per pixel or
  // pixels per degree.  At the moment, we haven't done the math to
  // convert ppd to meters in a projected coordinate system and mpp to
  // degrees in an unprojected coordinate system.  We throw an error
  // in these cases for now.
  double scale = 0;
  if (vm.count("ppd")) {
    if (dem_georef.is_projected()) {
      std::cout << "Input DEM is in a map projection.  Cannot specify resolution in pixels per degree.  Use meters per pixel (-mpp) instead.";
      exit(0);
    } else {
      scale = 1/ppd;
    }
  } else if (vm.count("mpp")) {
    if (dem_georef.is_projected()) {
      scale = mpp;
    } else {
      std::cout << "Input DEM is in a simple cylindrical map projection (Plate Carree).  Cannot specify resolution in meters per pixel.  Use pixels per degree (-ppd) instead.";
      exit(0);
    }
  }

  vw_out(0) << "\nOrthoprojecting:\n";

  // If the user has specified that we match the georeferencing
  // parameters of the DEM, we use the DEM's georef as the output
  // georef.  Otherwise we compute one of our own that contains the
  // entirety of the input image and matches the pixel scale of the
  // input image as closely as possible.
  if (vm.count("match-dem")) {
    write_georeferenced_image(output_file,
                              orthoproject(dem, dem_georef,
                                           texture_image, camera_model,
                                           BilinearInterpolation(), ZeroEdgeExtension()),
                              dem_georef,
                              TerminalProgressCallback() );
  }  else {
    double output_width, output_height;
    GeoReference output_georef = compute_geotransform_from_camera(texture_image, camera_model,
                                                                  dem, dem_georef, scale,
                                                                  output_width, output_height);
    GeoTransform trans(dem_georef, output_georef);
    ImageViewRef<PixelMask<PixelGray<float> > > output_dem = crop(transform(dem, trans,
                                                                ZeroEdgeExtension(),
                                                                BilinearInterpolation()),
                                                      BBox2i(0,0,output_width,output_height));
    write_georeferenced_image(output_file,
                              orthoproject(output_dem, output_georef,
                                           texture_image, camera_model,
                                           BilinearInterpolation(), ZeroEdgeExtension()),
                              output_georef,
                              TerminalProgressCallback() );
  }

}
<commit_msg>Switched to using block tiff writing for othroproject.<commit_after>/************************************************************************
 *     File: stereo.cc
 *     Date: April 2005
 *       By: Michael Broxton and Larry Edwards
 *      For: NASA Ames Research Center, Intelligent Mechanisms Group
 * Function: Main program for the stereo pipeline
 ************************************************************************/
#include <boost/algorithm/string.hpp>
#include <boost/program_options.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/convenience.hpp>
#include <boost/filesystem/fstream.hpp>
using namespace boost;
namespace po = boost::program_options;
namespace fs = boost::filesystem;

#include <vw/Core.h>
#include <vw/Image.h>
#include <vw/FileIO.h>
#include <vw/Camera.h>
#include <vw/Cartography.h>
#include <vw/Cartography/OrthoImageView.h>
using namespace vw;
using namespace vw::camera;
using namespace vw::cartography;

#include "asp_config.h"
#include "StereoSession.h"
using namespace std;

#if defined(ASP_HAVE_PKG_ISIS) && ASP_HAVE_PKG_ISIS == 1
#include "Isis/DiskImageResourceIsis.h"
#include "Isis/StereoSessionIsis.h"
#endif

#include "HRSC/StereoSessionHRSC.h"
#include "MOC/StereoSessionMOC.h"
#include "apollo/StereoSessionApolloMetric.h"
#include "MRO/StereoSessionCTX.h"
#include "RMAX/StereoSessionRmax.h"

// Allows FileIO to correctly read/write these pixel types
namespace vw {
  template<> struct PixelFormatID<Vector3>   { static const PixelFormatEnum value = VW_PIXEL_GENERIC_3_CHANNEL; };
}

template <class ViewT, class DemViewT>
GeoReference compute_geotransform_from_camera(ImageViewBase<ViewT> const& view,
                                              boost::shared_ptr<CameraModel> camera,
                                              ImageViewBase<DemViewT> const& dem,
                                              GeoReference const& dem_georef,
                                              double scale,
                                              double &output_width, double& output_height) {

  // Adopt the datum & projection of the parent DEM.
  GeoReference geo = dem_georef;

  // Compute the longitude/latitude bounding box and the lonlat pixel scale
  float lonlat_scale;
  BBox2 image_bbox = camera_bbox(dem_georef, camera, view.impl().cols(), view.impl().rows(), lonlat_scale);
  BBox2 dem_bbox = dem_georef.lonlat_bounding_box(dem);

  // Use a bbox where both the image and the DEM have valid data.
  // Throw an error if there turns out to be no overlap.
  BBox2 bbox = image_bbox;
  bbox.crop(dem_bbox);
  if (bbox.width() == 0 || bbox.height() == 0) {
    std::cout << "Image bounding box (" << image_bbox << ") and DEM bounding box (" << dem_bbox << ") have no overlap.  Are you sure that your input files overlap?\n";
    exit(0);
  }

  float diff1 = bbox.max().x()-bbox.min().x();

  // Convert the lon/lat bounding box into the map projection.
  bbox.min() = geo.lonlat_to_point(bbox.min());
  bbox.max() = geo.lonlat_to_point(bbox.max());
  float diff2 = bbox.max().x()-bbox.min().x();

  // Convert the scale into the projected space
  double projected_space_scale = lonlat_scale * diff2 / diff1;

  // If the user has supplied a scale, we override our computed value
  // here.
  if (scale != 0) {
    projected_space_scale = scale;
  }

  // Compute the affine transform for this image.
  Matrix3x3 trans = geo.transform();

  trans(0,0) = projected_space_scale;
  trans(1,1) = -projected_space_scale;
  trans(0,2) = bbox.min().x();
  trans(1,2) = bbox.max().y();
  geo.set_transform(trans);

  // Compute the width and height of the output image so that it
  // contains the entirety of the computed bounding box.
  output_width = (bbox.max().x() - bbox.min().x()) / projected_space_scale;
  output_height = (bbox.max().y() - bbox.min().y()) / projected_space_scale;

  return geo;
}

//***********************************************************************
// MAIN
//***********************************************************************

int main(int argc, char* argv[]) {

  /*************************************/
  /* Parsing of command line arguments */
  /*************************************/

  // Boost has a nice command line parsing utility, which we use here
  // to specify the type, size, help string, etc, of the command line
  // arguments.
  int debug_level;
  unsigned cache_size;
  std::string dem_file, image_file, camera_model_file, output_file;
  std::string stereo_session_string;
  double mpp;
  double ppd;
  double missing_pixel_value;
  float lo = 0, hi = 0;

  po::options_description visible_options("Options");
  visible_options.add_options()
    ("help,h", "Display this help message")
    ("mpp", po::value<double>(&mpp), "Specify the output resolution of the orthoimage in meters per pixel.")
    ("ppd", po::value<double>(&ppd), "Specify the output resolution of the orthoimage in pixels per degree.")
    ("missing-pixel", po::value<double>(&missing_pixel_value)->default_value(-6000), "Specify the pixel used in this DEM to denote missing data.")
    ("match-dem,m", "Match the georeferencing parameters and dimensions of the input DEM.")
    ("min", po::value<float>(&lo), "Explicitly specify the range of the normalization (for ISIS images only).")
    ("max", po::value<float>(&hi), "Explicitly specify the range of the normalization (for ISIS images only).")
    ("cache", po::value<unsigned>(&cache_size)->default_value(2048), "Cache size, in megabytes")
    ("session-type,t", po::value<std::string>(&stereo_session_string)->default_value("pinhole"), "Select the stereo session type to use for processing. [default: pinhole]")
    ("debug-level,d", po::value<int>(&debug_level)->default_value(vw::DebugMessage-1), "Set the debugging output level. (0-50+)");

  po::options_description positional_options("Positional Options");
  positional_options.add_options()
    ("dem", po::value<std::string>(&dem_file), "DEM Input File")
    ("camera-image", po::value<std::string>(&image_file), "Camera Input file")
    ("camera-model", po::value<std::string>(&camera_model_file), "Camera Model File")
    ("output-file", po::value<std::string>(&output_file), "Output filename");
  po::positional_options_description positional_options_desc;
  positional_options_desc.add("dem", 1);
  positional_options_desc.add("camera-image", 1);
  positional_options_desc.add("camera-model", 1);
  positional_options_desc.add("output-file", 1);

  po::options_description all_options;
  all_options.add(visible_options).add(positional_options);

  po::variables_map vm;
  po::store( po::command_line_parser( argc, argv ).options(all_options).positional(positional_options_desc).run(), vm );
  po::notify( vm );

  // If the command line wasn't properly formed or the user requested
  // help, we print an usage message.
  if( vm.count("help") ||
      !vm.count("dem") ||
      !vm.count("camera-image") || !vm.count("camera-model") ||
      !vm.count("output-file")) {
    std::cout << "\nUsage: orthoproject [options] <dem filename> <camera image> <camera model> <output filename>\n";
    std::cout << visible_options << std::endl;
    return 1;
  }

  // Set the Vision Workbench debug level
  set_debug_level(debug_level);
  Cache::system_cache().resize( cache_size*1024*1024 ); // Set cache to 1Gb

  // Create a fresh stereo session and query it for the camera models.
  StereoSession::register_session_type( "hrsc", &StereoSessionHRSC::construct);
  StereoSession::register_session_type( "moc", &StereoSessionMOC::construct);
  StereoSession::register_session_type( "metric", &StereoSessionApolloMetric::construct);
  StereoSession::register_session_type( "ctx", &StereoSessionCTX::construct);
  StereoSession::register_session_type( "rmax", &StereoSessionRmax::construct);
#if defined(ASP_HAVE_PKG_ISIS) && ASP_HAVE_PKG_ISIS == 1
  StereoSession::register_session_type( "isis", &StereoSessionIsis::construct);
#endif

  // Okay, here's a total hack.  We create a stereo session where both
  // of the imagers and images are the same, because we want to take
  // advantage of the stereo pipeline's ability to generate camera
  // models for various missions.  Hence, we create two identical
  // camera models, but only one is used.  The last four empty strings
  // are dummy arguments.
  StereoSession* session = StereoSession::create(stereo_session_string);
  session->initialize(image_file, image_file, camera_model_file, camera_model_file,
                      output_file, "", "","","" );
  boost::shared_ptr<camera::CameraModel> camera_model;
  camera_model = session->camera_model(image_file, camera_model_file);

  // Open the DEM
  GeoReference dem_georef;
  cartography::read_georeference(dem_georef, dem_file);

  DiskImageView<PixelGray<float> > dem_disk_image(dem_file);
  ImageViewRef<PixelMask<PixelGray<float> > > dem = pixel_cast<PixelMask<PixelGray<float> > >(dem_disk_image);

  if (vm.count("missing-pixel")) {
    std::cout << "\t--> Using " << missing_pixel_value << " as the missing data value for the DEM.\n";
    dem = create_mask(dem_disk_image, missing_pixel_value);
  }

  DiskImageView<PixelGrayA<uint8> > texture_disk_image(image_file);
  ImageViewRef<PixelGrayA<uint8> > texture_image = texture_disk_image;
  DiskImageView<PixelGrayA<float> > float_texture_disk_image(image_file);

  // ISIS cubes need to be normalized because their pixels are often
  // photometrically calibrated.
  if (stereo_session_string == "isis") {
    if (lo == 0 && hi == 0) {
      isis_min_max_channel_values(float_texture_disk_image, lo, hi);
      std::cout << "\t--> Normalizing ISIS pixel range range: [" << lo << "  " << hi << "]\n";
    } else {
      std::cout << "\t--> Using user-specified normalization range: [" << lo << "  " << hi << "]\n";
    }
    texture_image = channel_cast_rescale<uint8>(normalize_retain_alpha(remove_isis_special_pixels(float_texture_disk_image, PixelGrayA<float>(lo)), lo, hi, 0, 1.0));
  }

  // Parse the scale of the output image from the command line
  // arguments.  This value can be set either in meters per pixel or
  // pixels per degree.  At the moment, we haven't done the math to
  // convert ppd to meters in a projected coordinate system and mpp to
  // degrees in an unprojected coordinate system.  We throw an error
  // in these cases for now.
  double scale = 0;
  if (vm.count("ppd")) {
    if (dem_georef.is_projected()) {
      std::cout << "Input DEM is in a map projection.  Cannot specify resolution in pixels per degree.  Use meters per pixel (-mpp) instead.";
      exit(0);
    } else {
      scale = 1/ppd;
    }
  } else if (vm.count("mpp")) {
    if (dem_georef.is_projected()) {
      scale = mpp;
    } else {
      std::cout << "Input DEM is in a simple cylindrical map projection (Plate Carree).  Cannot specify resolution in meters per pixel.  Use pixels per degree (-ppd) instead.";
      exit(0);
    }
  }

  vw_out(0) << "\nOrthoprojecting:\n";

  // If the user has specified that we match the georeferencing
  // parameters of the DEM, we use the DEM's georef as the output
  // georef.  Otherwise we compute one of our own that contains the
  // entirety of the input image and matches the pixel scale of the
  // input image as closely as possible.
  if (vm.count("match-dem")) {
    write_georeferenced_image(output_file,
                              orthoproject(dem, dem_georef,
                                           texture_image, camera_model,
                                           BilinearInterpolation(), ZeroEdgeExtension()),
                              dem_georef,
                              TerminalProgressCallback() );
  }  else {
    double output_width, output_height;
    GeoReference output_georef = compute_geotransform_from_camera(texture_image, camera_model,
                                                                  dem, dem_georef, scale,
                                                                  output_width, output_height);
    GeoTransform trans(dem_georef, output_georef);
    ImageViewRef<PixelMask<PixelGray<float> > > output_dem = crop(transform(dem, trans,
                                                                            ZeroEdgeExtension(),
                                                                            BilinearInterpolation()),
                                                                  BBox2i(0,0,output_width,output_height));

    ImageViewRef<PixelGrayA<uint8> > final_result = orthoproject(output_dem, output_georef,
                                                                 texture_image, camera_model,
                                                                 BilinearInterpolation(), ZeroEdgeExtension());

    DiskImageResourceGDAL rsrc(output_file, final_result.format());
    rsrc.set_native_block_size(Vector2i(1024,1024));
    write_georeference(rsrc, output_georef);
    write_image(rsrc, final_result, TerminalProgressCallback());
  }
}
<|endoftext|>