<commit_before>#include "main.h"
#include "File.h"
#include "header.h"

namespace FileTMP {
    enum TypeCode {FLOAT32 = 0, FLOAT64, UINT8, INT8, UINT16, INT16, UINT32, INT32, UINT64, INT64};

    void help() {
        pprintf(".tmp files. This format is used to save temporary image data, and to"
                " interoperate with other programs that can load or save raw binary"
                " data. The format supports any number of frames and channels."
                " A .tmp file starts with a header that containining five 32-bit"
                " integer values which represents frames, width, height, channels and"
                " type. Image data follows.\n"
                "types:\n"
                " 0: 32 bit floats (the default format, which matches the internal format)\n"
                " 1: 64 bit doubles\n"
                " 2: 8 bit unsigned integers\n"
                " 3: 8 bit signed integers\n"
                " 4: 16 bit unsigned integers\n"
                " 5: 16 bit signed integers\n"
                " 6: 32 bit unsigned integers\n"
                " 7: 32 bit signed integers\n"
                " 8: 64 bit unsigned integers\n"
                " 9: 64 bit signed integers\n"
                "\n"
                "When saving, an optional second argument specifies the format. This"
                " may be any of int8, uint8, int16, uint16, int32, uint32, int64,"
                " uint64, float32, float64, or correspondingly char, unsigned"
                " char, short, unsigned short, int, unsigned int, float, or"
                " double. The default is float32.\n");
    }

    template<typename T>
    void saveData(FILE *f, Window im) {

        vector<T> buf(im.width*im.channels);

        for (int t = 0; t < im.frames; t++) {
            for (int y = 0; y < im.height; y++) {
                float *srcPtr = im(0, y, t);
                T *dstPtr = &buf[0];
                for (int j = 0; j < im.width*im.channels; j++) {
                    *dstPtr++ = (T)(*srcPtr++);
                }
                fwrite(&buf[0], sizeof(T), im.width*im.channels, f);
            }
        }
    }

    template<>
    void saveData<float>(FILE *f, Window im) {

        vector<float> buf(im.width*im.channels);

        for (int t = 0; t < im.frames; t++) {
            for (int y = 0; y < im.height; y++) {
                fwrite(im(0, y, t), sizeof(float), im.width*im.channels, f);
            }
        }
    }

    void save(Window im, string filename, string type) {
        FILE *f = fopen(filename.c_str(), "wb");
        assert(f, "Could not write output file %s\n", filename.c_str());
        // write the dimensions
        fwrite(&im.frames, sizeof(int), 1, f);
        fwrite(&im.width, sizeof(int), 1, f);
        fwrite(&im.height, sizeof(int), 1, f);
        fwrite(&im.channels, sizeof(int), 1, f);

        int typeCode;

        if (type == "float" || type == "float32") {
            typeCode = FLOAT32;
            fwrite(&typeCode, sizeof(int), 1, f);
            saveData<float>(f, im);
        } else if (type == "double" || type == "float64") {
            typeCode = FLOAT64;
            fwrite(&typeCode, sizeof(int), 1, f);
            saveData<double>(f, im);
        } else if (type == "uint8" || type == "unsigned char") {
            typeCode = UINT8;
            fwrite(&typeCode, sizeof(int), 1, f);
            saveData<unsigned char>(f, im);
        } else if (type == "int8" || type == "char") {
            typeCode = INT8;
            fwrite(&typeCode, sizeof(int), 1, f);
            saveData<signed char>(f, im);
        } else if (type == "uint16" || type == "unsigned short") {
            typeCode = UINT16;
            fwrite(&typeCode, sizeof(int), 1, f);
            saveData<unsigned short>(f, im);
        } else if (type == "int16" || type == "short") {
            typeCode = INT16;
            fwrite(&typeCode, sizeof(int), 1, f);
            saveData<signed short>(f, im);
        } else if (type == "uint32" || type == "unsigned int") {
            typeCode = UINT32;
            fwrite(&typeCode, sizeof(int), 1, f);
            saveData<unsigned long>(f, im);
        } else if (type == "int32" || type == "int") {
            typeCode = INT32;
            fwrite(&typeCode, sizeof(int), 1, f);
            saveData<signed long>(f, im);
        } else if (type == "uint64") {
            typeCode = UINT64;
            fwrite(&typeCode, sizeof(int), 1, f);
            saveData<unsigned long long>(f, im);
        } else if (type == "int64") {
            typeCode = INT64;
            fwrite(&typeCode, sizeof(int), 1, f);
            saveData<signed long long>(f, im);
        }
        fclose(f);
    }

    template<typename T>
    Image loadData(FILE *f, int frames, int width, int height, int channels) {
        int size = width * height * channels * frames;

        Image im(width, height, frames, channels);

        const size_t chunkSize = 1<<12;

        T buf[chunkSize];

        float *dstPtr = im(0, 0, 0);
        float *endPtr = im(0, 0, im.frames);

        T *srcPtr = &buf[0];
        for (int i = 0; i < size; i += chunkSize) {
            srcPtr = &buf[0];
            assert(fread(srcPtr, sizeof(T), chunkSize, f) == chunkSize,
                   "Unexpected end of file\n");
            for (size_t j = 0; j < chunkSize && dstPtr != endPtr; j++) {
                *dstPtr++ = (float)(*srcPtr++);
            }
        }

        return im;
    }

    template<>
    Image loadData<float>(FILE *f, int frames, int width, int height, int channels) {
        size_t size = width * height * channels * frames;

        Image im(width, height, frames, channels);

        assert(fread(im(0, 0, 0), sizeof(float), size, f) == size,
               "Unexpected end of file\n");

        return im;
    }

    Image load(string filename) {
        FILE *file = fopen(filename.c_str(), "rb");
        assert(file, "Could not open file %s\n", filename.c_str());

        // get the dimensions
        struct header_t {
            int frames, width, height, channels, typeCode;
        } h;
        assert(fread(&h, sizeof(int), 5, file) == 5,
               "File ended before end of header\n");

        Image im;

        if (h.typeCode == FLOAT32) {
            im = loadData<float>(file, h.frames, h.width, h.height, h.channels);
        } else if (h.typeCode == FLOAT64) {
            im = loadData<double>(file, h.frames, h.width, h.height, h.channels);
        } else if (h.typeCode == UINT8) {
            im = loadData<unsigned char>(file, h.frames, h.width, h.height, h.channels);
        } else if (h.typeCode == INT8) {
            im = loadData<signed char>(file, h.frames, h.width, h.height, h.channels);
        } else if (h.typeCode == UINT16) {
            im = loadData<unsigned short>(file, h.frames, h.width, h.height, h.channels);
        } else if (h.typeCode == INT16) {
            im = loadData<signed short>(file, h.frames, h.width, h.height, h.channels);
        } else if (h.typeCode == UINT32) {
            im = loadData<unsigned long>(file, h.frames, h.width, h.height, h.channels);
        } else if (h.typeCode == INT32) {
            im = loadData<signed long>(file, h.frames, h.width, h.height, h.channels);
        } else if (h.typeCode == UINT64) {
            im = loadData<unsigned long long>(file, h.frames, h.width, h.height, h.channels);
        } else if (h.typeCode == INT64) {
            im = loadData<signed long long>(file, h.frames, h.width, h.height, h.channels);
        } else {
            printf("Unknown type code %d. Possibly trying to load an old-style tmp file.\n", h.typeCode);
            fseek(file, 16, SEEK_SET);
            im = loadData<float>(file, h.frames, h.width, h.height, h.channels);
        }

        fclose(file);

        return im;
    }
}
#include "footer.h"
<commit_msg>Fixed loadTMP to work on non-power-of-2 images<commit_after>#include "main.h"
#include "File.h"
#include "header.h"

namespace FileTMP {
    enum TypeCode {FLOAT32 = 0, FLOAT64, UINT8, INT8, UINT16, INT16, UINT32, INT32, UINT64, INT64};

    void help() {
        pprintf(".tmp files. This format is used to save temporary image data, and to"
                " interoperate with other programs that can load or save raw binary"
                " data. The format supports any number of frames and channels."
                " A .tmp file starts with a header that containining five 32-bit"
                " integer values which represents frames, width, height, channels and"
                " type. Image data follows.\n"
                "types:\n"
                " 0: 32 bit floats (the default format, which matches the internal format)\n"
                " 1: 64 bit doubles\n"
                " 2: 8 bit unsigned integers\n"
                " 3: 8 bit signed integers\n"
                " 4: 16 bit unsigned integers\n"
                " 5: 16 bit signed integers\n"
                " 6: 32 bit unsigned integers\n"
                " 7: 32 bit signed integers\n"
                " 8: 64 bit unsigned integers\n"
                " 9: 64 bit signed integers\n"
                "\n"
                "When saving, an optional second argument specifies the format. This"
                " may be any of int8, uint8, int16, uint16, int32, uint32, int64,"
                " uint64, float32, float64, or correspondingly char, unsigned"
                " char, short, unsigned short, int, unsigned int, float, or"
                " double. The default is float32.\n");
    }

    template<typename T>
    void saveData(FILE *f, Window im) {

        vector<T> buf(im.width*im.channels);

        for (int t = 0; t < im.frames; t++) {
            for (int y = 0; y < im.height; y++) {
                float *srcPtr = im(0, y, t);
                T *dstPtr = &buf[0];
                for (int j = 0; j < im.width*im.channels; j++) {
                    *dstPtr++ = (T)(*srcPtr++);
                }
                fwrite(&buf[0], sizeof(T), im.width*im.channels, f);
            }
        }
    }

    template<>
    void saveData<float>(FILE *f, Window im) {

        vector<float> buf(im.width*im.channels);

        for (int t = 0; t < im.frames; t++) {
            for (int y = 0; y < im.height; y++) {
                fwrite(im(0, y, t), sizeof(float), im.width*im.channels, f);
            }
        }
    }

    void save(Window im, string filename, string type) {
        FILE *f = fopen(filename.c_str(), "wb");
        assert(f, "Could not write output file %s\n", filename.c_str());
        // write the dimensions
        fwrite(&im.frames, sizeof(int), 1, f);
        fwrite(&im.width, sizeof(int), 1, f);
        fwrite(&im.height, sizeof(int), 1, f);
        fwrite(&im.channels, sizeof(int), 1, f);

        int typeCode;

        if (type == "float" || type == "float32") {
            typeCode = FLOAT32;
            fwrite(&typeCode, sizeof(int), 1, f);
            saveData<float>(f, im);
        } else if (type == "double" || type == "float64") {
            typeCode = FLOAT64;
            fwrite(&typeCode, sizeof(int), 1, f);
            saveData<double>(f, im);
        } else if (type == "uint8" || type == "unsigned char") {
            typeCode = UINT8;
            fwrite(&typeCode, sizeof(int), 1, f);
            saveData<unsigned char>(f, im);
        } else if (type == "int8" || type == "char") {
            typeCode = INT8;
            fwrite(&typeCode, sizeof(int), 1, f);
            saveData<signed char>(f, im);
        } else if (type == "uint16" || type == "unsigned short") {
            typeCode = UINT16;
            fwrite(&typeCode, sizeof(int), 1, f);
            saveData<unsigned short>(f, im);
        } else if (type == "int16" || type == "short") {
            typeCode = INT16;
            fwrite(&typeCode, sizeof(int), 1, f);
            saveData<signed short>(f, im);
        } else if (type == "uint32" || type == "unsigned int") {
            typeCode = UINT32;
            fwrite(&typeCode, sizeof(int), 1, f);
            saveData<unsigned long>(f, im);
        } else if (type == "int32" || type == "int") {
            typeCode = INT32;
            fwrite(&typeCode, sizeof(int), 1, f);
            saveData<signed long>(f, im);
        } else if (type == "uint64") {
            typeCode = UINT64;
            fwrite(&typeCode, sizeof(int), 1, f);
            saveData<unsigned long long>(f, im);
        } else if (type == "int64") {
            typeCode = INT64;
            fwrite(&typeCode, sizeof(int), 1, f);
            saveData<signed long long>(f, im);
        }
        fclose(f);
    }

    template<typename T>
    Image loadData(FILE *f, int frames, int width, int height, int channels) {
        int size = width * height * channels * frames;

        Image im(width, height, frames, channels);

        const size_t chunkSize = 1<<12;

        T buf[chunkSize];

        float *dstPtr = im(0, 0, 0);
        float *endPtr = im(0, 0, im.frames);

        T *srcPtr = &buf[0];
        for (int i = 0; i < size; i += chunkSize) {
	    srcPtr = &buf[0];
	    size_t sizeLeft = size - i - 1;
	    size_t expectedSize = (sizeLeft < chunkSize) ? sizeLeft : chunkSize;
	    assert(fread(srcPtr, sizeof(T), expectedSize, f) == expectedSize,
                   "Unexpected end of file\n");
            for (size_t j = 0; j < chunkSize && dstPtr != endPtr; j++) {
                *dstPtr++ = (float)(*srcPtr++);
            }
        }

        return im;
    }

    template<>
    Image loadData<float>(FILE *f, int frames, int width, int height, int channels) {
        size_t size = width * height * channels * frames;

        Image im(width, height, frames, channels);

        assert(fread(im(0, 0, 0), sizeof(float), size, f) == size,
               "Unexpected end of file\n");

        return im;
    }

    Image load(string filename) {
        FILE *file = fopen(filename.c_str(), "rb");
        assert(file, "Could not open file %s\n", filename.c_str());

        // get the dimensions
        struct header_t {
            int frames, width, height, channels, typeCode;
        } h;
        assert(fread(&h, sizeof(int), 5, file) == 5,
               "File ended before end of header\n");

        Image im;

        if (h.typeCode == FLOAT32) {
            im = loadData<float>(file, h.frames, h.width, h.height, h.channels);
        } else if (h.typeCode == FLOAT64) {
            im = loadData<double>(file, h.frames, h.width, h.height, h.channels);
        } else if (h.typeCode == UINT8) {
            im = loadData<unsigned char>(file, h.frames, h.width, h.height, h.channels);
        } else if (h.typeCode == INT8) {
            im = loadData<signed char>(file, h.frames, h.width, h.height, h.channels);
        } else if (h.typeCode == UINT16) {
            im = loadData<unsigned short>(file, h.frames, h.width, h.height, h.channels);
        } else if (h.typeCode == INT16) {
            im = loadData<signed short>(file, h.frames, h.width, h.height, h.channels);
        } else if (h.typeCode == UINT32) {
            im = loadData<unsigned long>(file, h.frames, h.width, h.height, h.channels);
        } else if (h.typeCode == INT32) {
            im = loadData<signed long>(file, h.frames, h.width, h.height, h.channels);
        } else if (h.typeCode == UINT64) {
            im = loadData<unsigned long long>(file, h.frames, h.width, h.height, h.channels);
        } else if (h.typeCode == INT64) {
            im = loadData<signed long long>(file, h.frames, h.width, h.height, h.channels);
        } else {
            printf("Unknown type code %d. Possibly trying to load an old-style tmp file.\n", h.typeCode);
            fseek(file, 16, SEEK_SET);
            im = loadData<float>(file, h.frames, h.width, h.height, h.channels);
        }

        fclose(file);

        return im;
    }
}
#include "footer.h"
<|endoftext|>


<commit_before>#ifndef LTSF_QUEUE_HPP
#define LTSF_QUEUE_HPP

#include <memory>

namespace warped {

class Event;

class LTSFQueue {
public:
    virtual ~LTSFQueue() {}
    virtual bool empty() const = 0;
    virtual unsigned int size() const = 0;
    virtual Event* peek() const = 0;
    virtual std::unique_ptr<Event> pop() = 0;
    virtual void push(std::unique_ptr<Event> event) = 0;
    virtual void push(std::vector<std::unique_ptr<Event>>& events) = 0;
    virtual void push(std::vector<std::unique_ptr<Event>>&& events) = 0;
};

} // namespace warped

#endif<commit_msg>Added include<commit_after>#ifndef LTSF_QUEUE_HPP
#define LTSF_QUEUE_HPP

#include <memory>
#include <vector>

namespace warped {

class Event;

class LTSFQueue {
public:
    virtual ~LTSFQueue() {}
    virtual bool empty() const = 0;
    virtual unsigned int size() const = 0;
    virtual Event* peek() const = 0;
    virtual std::unique_ptr<Event> pop() = 0;
    virtual void push(std::unique_ptr<Event> event) = 0;
    virtual void push(std::vector<std::unique_ptr<Event>>& events) = 0;
    virtual void push(std::vector<std::unique_ptr<Event>>&& events) = 0;
};

} // namespace warped

#endif<|endoftext|>


<commit_before>#include "Cluster.h"

using namespace std;

Cluster::Cluster(vector<map<string, double>*> &hypers_v) {
  init_columns(hypers_v);
}

Cluster::Cluster() {
  vector<map<string, double>*> hypers_v;
  init_columns(hypers_v);
}

void Cluster::delete_component_models(bool check_empty) {
  if(check_empty) {
    assert(row_indices.size()==0);
  }
  while(p_model_v.size()!=0) {
    ComponentModel *p_cm = p_model_v.back();
    p_model_v.pop_back();
    delete p_cm;
  }
}

int Cluster::get_num_cols() const {
  return p_model_v.size();
}

int Cluster::get_count() const {
  return row_indices.size();
}

double Cluster::get_marginal_logp() const {
  return score;
}

map<string, double> Cluster::get_suffstats_i(int idx) const {
  return p_model_v[idx]->get_suffstats();
}

map<string, double> Cluster::get_hypers_i(int idx) const {
  return p_model_v[idx]->get_hypers();
}

set<int> Cluster::get_row_indices_set() const {
  return row_indices;
}

vector<int> Cluster::get_row_indices_vector() const {
  return set_to_vector(row_indices);
}

std::vector<double> Cluster::calc_marginal_logps() const {
  std::vector<double> logps;
  typename std::vector<ComponentModel*>::const_iterator it;
  for(it=p_model_v.begin(); it!=p_model_v.end(); it++) {
    double logp = (**it).calc_marginal_logp();
    logps.push_back(logp);
  }
  return logps;
}

double Cluster::calc_sum_marginal_logps() const {
  std::vector<double> logp_map = calc_marginal_logps();
  double sum_logps = std::accumulate(logp_map.begin(), logp_map.end(), 0.);
  return sum_logps;
}

double Cluster::calc_row_predictive_logp(vector<double> values) const {
  double sum_logps = 0;
  for(unsigned int col_idx=0; col_idx<values.size(); col_idx++) {
    double el = values[col_idx];
    sum_logps += p_model_v[col_idx]->calc_element_predictive_logp(el);
  }
  return sum_logps;
}

vector<double> Cluster::calc_hyper_conditionals(int which_col,
						string which_hyper,
						vector<double> hyper_grid) const {
  ComponentModel *ccm = p_model_v[which_col];
  vector<double> hyper_conditionals = ccm->calc_hyper_conditionals(which_hyper,
								  hyper_grid);
  return hyper_conditionals;
}

double Cluster::calc_column_predictive_logp(vector<double> column_data,
					    string col_datatype,
					    vector<int> data_global_row_indices,
					    map<string, double> hypers) {
  map<int, int> global_to_data = construct_lookup_map(data_global_row_indices);
  ComponentModel *p_cm;
  if(col_datatype==CONTINUOUS_DATATYPE) {
    p_cm = new ContinuousComponentModel(hypers);
  } else if(col_datatype==CONTINUOUS_DATATYPE) {
    p_cm = new MultinomialComponentModel(hypers);
  } else {
    assert(1==0);
  }
  set<int>::iterator it;
  for(it=row_indices.begin(); it!=row_indices.end(); it++) {
    int global_row_idx = *it;
    int data_idx = global_to_data[global_row_idx];
    double value = column_data[data_idx];
    p_cm->insert_element(value);
  }
  double score_delta = p_cm->calc_marginal_logp();
  delete p_cm;
  return score_delta;
}

double Cluster::insert_row(vector<double> values, int row_idx) {
  double sum_score_deltas = 0;
  // track row indices
  pair<set<int>::iterator, bool> set_pair = \
    row_indices.insert(row_idx);
  assert(set_pair.second);
  // track score
  for(unsigned int col_idx=0; col_idx<values.size(); col_idx++) {
    sum_score_deltas += p_model_v[col_idx]->insert_element(values[col_idx]);
  }
  score += sum_score_deltas;
  return sum_score_deltas;
}

double Cluster::remove_row(vector<double> values, int row_idx) {
  double sum_score_deltas = 0;
  // track row indices
  unsigned int num_removed = row_indices.erase(row_idx);
  assert(num_removed!=0);
  // track score
  for(unsigned int col_idx=0; col_idx<values.size(); col_idx++) {
    double value_to_remove = values[col_idx];
    ComponentModel *p_cm = p_model_v[col_idx];
    sum_score_deltas += p_cm->remove_element(value_to_remove);
  }
  score += sum_score_deltas;
  return sum_score_deltas;
}

double Cluster::remove_col(int col_idx) {
  double score_delta = p_model_v[col_idx]->calc_marginal_logp();
  // FIXME: make sure destruction proper
  ComponentModel *p_cm = p_model_v[col_idx];
  p_model_v.erase(p_model_v.begin() + col_idx);
  delete p_cm;
  score -= score_delta;
  return score_delta;
}

double Cluster::insert_col(vector<double> data,
			   string col_datatype,
			   vector<int> data_global_row_indices,
			   map<string, double> &hypers) {
  map<int, int> global_to_data = construct_lookup_map(data_global_row_indices);
  ComponentModel *p_cm;
  if(col_datatype==CONTINUOUS_DATATYPE) {
    p_cm = new ContinuousComponentModel(hypers);
  } else if(col_datatype==CONTINUOUS_DATATYPE) {
    p_cm = new MultinomialComponentModel(hypers);
  } else {
    assert(1==0);
  }
  set<int>::iterator it;
  for(it=row_indices.begin(); it!=row_indices.end(); it++) {
    int global_row_idx = *it;
    int data_idx = global_to_data[global_row_idx];
    double value = data[data_idx];
    p_cm->insert_element(value);
  }
  double score_delta = p_cm->calc_marginal_logp();
  p_model_v.push_back(p_cm);
  score += score_delta;
  //
  return score_delta;
}

double Cluster::incorporate_hyper_update(int which_col) {
  double score_delta = p_model_v[which_col]->incorporate_hyper_update();
  score += score_delta;
  return score_delta;
}

std::ostream& operator<<(std::ostream& os, const Cluster& c) {
  os << c.to_string() << endl;
  return os;
}

string Cluster::to_string(string join_str, bool top_level) const {
  stringstream ss;
  if(!top_level) {
    ss << "========" << std::endl;
    ss <<  "row_indices:: " << row_indices;
    for(int col_idx=0; col_idx<get_num_cols(); col_idx++) {
      ss << join_str << "column idx: " << col_idx << " :: ";
      ss << *(p_model_v[col_idx]);
    }
    ss << "========" << std::endl;
  }
  ss << "cluster marginal logp: " << get_marginal_logp() << std::endl;
  return ss.str();
}

void Cluster::init_columns(vector<map<string, double>*> &hypers_v) {
  score = 0;
  vector<map<string, double>*>::iterator it;
  for(it=hypers_v.begin(); it!=hypers_v.end(); it++) {
    map<string, double> &hypers = **it;
    string continuous_key = "nu";
    string multinomial_key = "multinomial_alpha";
    ComponentModel *p_cm;
    if(in(hypers, continuous_key)) {
      // FIXME: should be passed col_datatypes here
      //         and instantiate correct type?
      p_cm = new ContinuousComponentModel(hypers);
      p_model_v.push_back(p_cm);
    } else if(in(hypers, multinomial_key)) {
      p_cm = new MultinomialComponentModel(hypers);
      p_model_v.push_back(p_cm);
    } else {
      assert(1==0);
    }
    int col_idx = p_model_v.size() - 1;
    score += p_model_v[col_idx]->calc_marginal_logp();
  }
}
<commit_msg>correct bug<commit_after>#include "Cluster.h"

using namespace std;

Cluster::Cluster(vector<map<string, double>*> &hypers_v) {
  init_columns(hypers_v);
}

Cluster::Cluster() {
  vector<map<string, double>*> hypers_v;
  init_columns(hypers_v);
}

void Cluster::delete_component_models(bool check_empty) {
  if(check_empty) {
    assert(row_indices.size()==0);
  }
  while(p_model_v.size()!=0) {
    ComponentModel *p_cm = p_model_v.back();
    p_model_v.pop_back();
    delete p_cm;
  }
}

int Cluster::get_num_cols() const {
  return p_model_v.size();
}

int Cluster::get_count() const {
  return row_indices.size();
}

double Cluster::get_marginal_logp() const {
  return score;
}

map<string, double> Cluster::get_suffstats_i(int idx) const {
  return p_model_v[idx]->get_suffstats();
}

map<string, double> Cluster::get_hypers_i(int idx) const {
  return p_model_v[idx]->get_hypers();
}

set<int> Cluster::get_row_indices_set() const {
  return row_indices;
}

vector<int> Cluster::get_row_indices_vector() const {
  return set_to_vector(row_indices);
}

std::vector<double> Cluster::calc_marginal_logps() const {
  std::vector<double> logps;
  typename std::vector<ComponentModel*>::const_iterator it;
  for(it=p_model_v.begin(); it!=p_model_v.end(); it++) {
    double logp = (**it).calc_marginal_logp();
    logps.push_back(logp);
  }
  return logps;
}

double Cluster::calc_sum_marginal_logps() const {
  std::vector<double> logp_map = calc_marginal_logps();
  double sum_logps = std::accumulate(logp_map.begin(), logp_map.end(), 0.);
  return sum_logps;
}

double Cluster::calc_row_predictive_logp(vector<double> values) const {
  double sum_logps = 0;
  for(unsigned int col_idx=0; col_idx<values.size(); col_idx++) {
    double el = values[col_idx];
    sum_logps += p_model_v[col_idx]->calc_element_predictive_logp(el);
  }
  return sum_logps;
}

vector<double> Cluster::calc_hyper_conditionals(int which_col,
						string which_hyper,
						vector<double> hyper_grid) const {
  ComponentModel *ccm = p_model_v[which_col];
  vector<double> hyper_conditionals = ccm->calc_hyper_conditionals(which_hyper,
								  hyper_grid);
  return hyper_conditionals;
}

double Cluster::calc_column_predictive_logp(vector<double> column_data,
					    string col_datatype,
					    vector<int> data_global_row_indices,
					    map<string, double> hypers) {
  map<int, int> global_to_data = construct_lookup_map(data_global_row_indices);
  ComponentModel *p_cm;
  if(col_datatype==CONTINUOUS_DATATYPE) {
    p_cm = new ContinuousComponentModel(hypers);
  } else if(col_datatype==CONTINUOUS_DATATYPE) {
    p_cm = new MultinomialComponentModel(hypers);
  } else {
    assert(1==0);
  }
  set<int>::iterator it;
  for(it=row_indices.begin(); it!=row_indices.end(); it++) {
    int global_row_idx = *it;
    int data_idx = global_to_data[global_row_idx];
    double value = column_data[data_idx];
    p_cm->insert_element(value);
  }
  double score_delta = p_cm->calc_marginal_logp();
  delete p_cm;
  return score_delta;
}

double Cluster::insert_row(vector<double> values, int row_idx) {
  double sum_score_deltas = 0;
  // track row indices
  pair<set<int>::iterator, bool> set_pair = \
    row_indices.insert(row_idx);
  assert(set_pair.second);
  // track score
  for(unsigned int col_idx=0; col_idx<values.size(); col_idx++) {
    sum_score_deltas += p_model_v[col_idx]->insert_element(values[col_idx]);
  }
  score += sum_score_deltas;
  return sum_score_deltas;
}

double Cluster::remove_row(vector<double> values, int row_idx) {
  double sum_score_deltas = 0;
  // track row indices
  unsigned int num_removed = row_indices.erase(row_idx);
  assert(num_removed!=0);
  // track score
  for(unsigned int col_idx=0; col_idx<values.size(); col_idx++) {
    double value_to_remove = values[col_idx];
    ComponentModel *p_cm = p_model_v[col_idx];
    sum_score_deltas += p_cm->remove_element(value_to_remove);
  }
  score += sum_score_deltas;
  return sum_score_deltas;
}

double Cluster::remove_col(int col_idx) {
  double score_delta = p_model_v[col_idx]->calc_marginal_logp();
  // FIXME: make sure destruction proper
  ComponentModel *p_cm = p_model_v[col_idx];
  p_model_v.erase(p_model_v.begin() + col_idx);
  delete p_cm;
  score -= score_delta;
  return score_delta;
}

double Cluster::insert_col(vector<double> data,
			   string col_datatype,
			   vector<int> data_global_row_indices,
			   map<string, double> &hypers) {
  map<int, int> global_to_data = construct_lookup_map(data_global_row_indices);
  ComponentModel *p_cm;
  if(col_datatype==CONTINUOUS_DATATYPE) {
    p_cm = new ContinuousComponentModel(hypers);
  } else if(col_datatype==MULTINOMIAL_DATATYPE) {
    p_cm = new MultinomialComponentModel(hypers);
  } else {
    assert(1==0);
  }
  set<int>::iterator it;
  for(it=row_indices.begin(); it!=row_indices.end(); it++) {
    int global_row_idx = *it;
    int data_idx = global_to_data[global_row_idx];
    double value = data[data_idx];
    p_cm->insert_element(value);
  }
  double score_delta = p_cm->calc_marginal_logp();
  p_model_v.push_back(p_cm);
  score += score_delta;
  //
  return score_delta;
}

double Cluster::incorporate_hyper_update(int which_col) {
  double score_delta = p_model_v[which_col]->incorporate_hyper_update();
  score += score_delta;
  return score_delta;
}

std::ostream& operator<<(std::ostream& os, const Cluster& c) {
  os << c.to_string() << endl;
  return os;
}

string Cluster::to_string(string join_str, bool top_level) const {
  stringstream ss;
  if(!top_level) {
    ss << "========" << std::endl;
    ss <<  "row_indices:: " << row_indices;
    for(int col_idx=0; col_idx<get_num_cols(); col_idx++) {
      ss << join_str << "column idx: " << col_idx << " :: ";
      ss << *(p_model_v[col_idx]);
    }
    ss << "========" << std::endl;
  }
  ss << "cluster marginal logp: " << get_marginal_logp() << std::endl;
  return ss.str();
}

void Cluster::init_columns(vector<map<string, double>*> &hypers_v) {
  score = 0;
  vector<map<string, double>*>::iterator it;
  for(it=hypers_v.begin(); it!=hypers_v.end(); it++) {
    map<string, double> &hypers = **it;
    string continuous_key = "nu";
    string multinomial_key = "multinomial_alpha";
    ComponentModel *p_cm;
    if(in(hypers, continuous_key)) {
      // FIXME: should be passed col_datatypes here
      //         and instantiate correct type?
      p_cm = new ContinuousComponentModel(hypers);
      p_model_v.push_back(p_cm);
    } else if(in(hypers, multinomial_key)) {
      p_cm = new MultinomialComponentModel(hypers);
      p_model_v.push_back(p_cm);
    } else {
      assert(1==0);
    }
    int col_idx = p_model_v.size() - 1;
    score += p_model_v[col_idx]->calc_marginal_logp();
  }
}
<|endoftext|>


<commit_before>#ifndef __CLUSTER_HPP_INCLUDED
#define __CLUSTER_HPP_INCLUDED

#include "vector"
#include "map"
#include "Options.hpp"
#include <iostream>
#include <string>
#include <fstream>
#include "Mesh.hpp"
#include "Matrix.hpp"
#include "Array1d_double64.hpp"
#include "Data.hpp"

class Cluster
{

public:
    Cluster(){}
    void initialization(map <string, string>, Mesh&);
    /* 'new' data created inside the app */

    int get_nSubClst(){return nSubClst;}
    int get_neqClst(){return neqClst;}
    int get_nLam_c(){return nLam_c;}
    int get_nLam_f(){return nLam_f;}
    int get_nRBM_f(){return nRBM_f;}
    int get_nRBM_c(){return nRBM_c;}

    void set_nSubClst(int);
    void set_neqClst(int);
    void set_nLam_c(int);
    void set_nLam_f(int);
    void set_nRBM_f(int);
    void set_nRBM_c(int);

    string folder;
    std::vector< Matrix> K;
    std::vector< Vector > rhs;

    std::vector< Matrix> Preconditioner;

    std::vector< Matrix> Kss;
    std::vector< Matrix> Krs;
    std::vector< Matrix> Krr;

    std::vector< Matrix> R;
    std::vector< Matrix> Fc;
    std::vector< Matrix> Bc;
    std::vector< Matrix> KplusBcT;
    std::vector< Matrix> Bf;
    std::vector< Matrix> BcT_dense;
    std::vector< Matrix> Gc;
    std::vector< Matrix > Rf;
    std::vector< Matrix > Gf;

    Mesh mesh;
    Data data;

    Matrix Fc_clust;
    Matrix Sc_clust;
    Matrix Gc_clust;
    Matrix Ac_clust;
    Matrix Gf_clust;
    Matrix GcTGc_clust;
    Matrix kerGc;

    Matrix GcTGc_sparse_clust;
    Matrix GfTGf;

    Matrix invGfTGf;

    map <string, string> options2;

    /* FETI */
    void create_Gf_clust();

    /* HFETI */
    void create_clust_object(Matrix &, vector <Matrix> & , bool);
    void create_Fc_clust();
    void create_Gc_clust();
    void create_Ac_clust(bool);
    void create_GcTGc();
    void create_GcTGc_clust_sparse();
    void create_GfTGf();
    void compute_invGfTGf();

    vector < double > weigth;

    /* dual */

    /* constraints */
    vector < vector < int > > neighbours;

    void create_cluster_constraints(const map <string, string> &);
    void create_Bc_or_Bf_in_CSR(vector <Matrix> &, bool , bool);
    void create_Bc_or_Bf_in_CSR(vector <Matrix> &, bool , bool, bool);
    void create_Bc_weightedAverages_in_COO(vector <Matrix> &, bool);
    void create_Rf_and_Gf();

    void matrix_Bx_COO2CSR(vector <Matrix> &, int);

    void mult_Kplus_f(vector < Vector > & , vector < Vector > &);
    void mult_Bf(vector < Vector > const &, Vector &);
    void mult_BfT(Vector  const &, vector < Vector > &);
    void mult_Gf(Vector const &, Vector &);
    void mult_GfT(Vector const &, Vector &);
    void mult_RfT(vector < Vector > const &, Vector&);
    void Projection(Vector const & , Vector &, Vector &);

    void mult_Ff(Vector const &, Vector &);
    void Preconditioning(Vector const &, Vector &);
    void scale(Vector &);

    void pcpg_old();
    void pcpg();
    void printVTK(vector < Vector > &, vector < Vector > &, Vector &, Vector &, int);

//    static double dot(Matrix &, Matrix &);
//    static double apb(Matrix &, Matrix &, double, double);
private:

    int nSubClst;
    int neqClst;
    int nLam_c;
    int nLam_f;
    int nRBM_f;
    int nRBM_c;

    double time_solver;
    double time_total;

};

#endif
<commit_msg>mesh changed to pointer, added dbg mode for Kplus, cosmetics ...<commit_after>#ifndef __CLUSTER_HPP_INCLUDED
#define __CLUSTER_HPP_INCLUDED

#include "vector"
#include "map"
#include "Options.hpp"
#include <iostream>
#include <string>
#include <fstream>
#include "Mesh.hpp"
#include "Matrix.hpp"
#include "Array1d_double64.hpp"
#include "Data.hpp"

class Cluster
{

public:
    Cluster(){}
    void initialization(map <string, string>, Mesh&);
    /* 'new' data created inside the app */

    int get_nSubClst(){return nSubClst;}
    int get_neqClst(){return neqClst;}
    int get_nLam_c(){return nLam_c;}
    int get_nLam_f(){return nLam_f;}
    int get_nRBM_f(){return nRBM_f;}
    int get_nRBM_c(){return nRBM_c;}

    void set_nSubClst(int);
    void set_neqClst(int);
    void set_nLam_c(int);
    void set_nLam_f(int);
    void set_nRBM_f(int);
    void set_nRBM_c(int);

    string folder;
    std::vector< Matrix> K;
    std::vector< Vector > rhs;

    std::vector< Matrix> Preconditioner;

    std::vector< Matrix> Kss;
    std::vector< Matrix> Krs;
    std::vector< Matrix> Krr;

    std::vector< Matrix> R;
    std::vector< Matrix> Fc;
    std::vector< Matrix> Bc;
    std::vector< Matrix> KplusBcT;
    std::vector< Matrix> Bf;
    std::vector< Matrix> BcT_dense;
    std::vector< Matrix> Gc;
    std::vector< Matrix > Rf;
    std::vector< Matrix > Gf;

    Mesh *mesh;
    Data data;

    Matrix Fc_clust;
    Matrix Sc_clust;
    Matrix Gc_clust;
    Matrix Ac_clust;
    Matrix Gf_clust;
    Matrix GcTGc_clust;
    Matrix kerGc;

    Matrix GcTGc_sparse_clust;
    Matrix GfTGf;

    Matrix invGfTGf;

    map <string, string> options2;

    /* FETI */
    void create_Gf_clust();

    /* HFETI */
    void create_clust_object(Matrix &, vector <Matrix> & , bool);
    void create_Fc_clust();
    void create_Gc_clust();
    void create_Ac_clust(bool);
    void create_GcTGc();
    void create_GcTGc_clust_sparse();
    void create_GfTGf();
    void compute_invGfTGf();

    vector < double > weigth;

    /* dual */

    /* constraints */
    vector < vector < int > > neighbours;

    void create_cluster_constraints(const map <string, string> &);
    void create_Bc_or_Bf_in_CSR(vector <Matrix> &, bool , bool);
    void create_Bc_or_Bf_in_CSR(vector <Matrix> &, bool , bool, bool);
    void create_Bc_weightedAverages_in_COO(vector <Matrix> &, bool);
    void create_Rf_and_Gf();

    void matrix_Bx_COO2CSR(vector <Matrix> &, int);

    void mult_Kplus_f(vector < Vector > & , vector < Vector > &);
    void mult_Kplus_f(vector < Vector > & , vector < Vector > &, int);
    void mult_Bf(vector < Vector > const &, Vector &);
    void mult_BfT(Vector  const &, vector < Vector > &);
    void mult_Gf(Vector const &, Vector &);
    void mult_GfT(Vector const &, Vector &);
    void mult_RfT(vector < Vector > const &, Vector&);
    void Projection(Vector const & , Vector &, Vector &);

    void mult_Ff(Vector const &, Vector &);
    void Preconditioning(Vector const &, Vector &);
    void scale(Vector &);

    void pcpg_old();
    void pcpg();
    void printVTK(vector < Vector > &, vector < Vector > &, Vector &, Vector &, int);

//    static double dot(Matrix &, Matrix &);
//    static double apb(Matrix &, Matrix &, double, double);
private:

    int nSubClst;
    int neqClst;
    int nLam_c;
    int nLam_f;
    int nRBM_f;
    int nRBM_c;

    double time_solver;
    double time_total;

};

#endif
<|endoftext|>


<commit_before>/*
    Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz>

    This file is part of Magnum.

    Magnum is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License version 3
    only, as published by the Free Software Foundation.

    Magnum is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU Lesser General Public License version 3 for more details.
*/

#include "Context.h"

#include <string>
#include <unordered_map>
#include <Utility/Debug.h>

#include "AbstractShaderProgram.h"
#include "AbstractTexture.h"
#include "Buffer.h"
#include "BufferedTexture.h"
#include "Extensions.h"
#include "IndexedMesh.h"
#include "Mesh.h"
#include "Implementation/State.h"

using namespace std;

namespace Magnum {

const std::vector<Extension>& Extension::extensions(Version version) {
    #define _extension(prefix, vendor, extension)                           \
        {Extensions::prefix::vendor::extension::Index, Extensions::prefix::vendor::extension::requiredVersion(), Extensions::prefix::vendor::extension::coreVersion(), Extensions::prefix::vendor::extension::string()}
    static const std::vector<Extension> empty;
    #ifndef MAGNUM_TARGET_GLES
    static const std::vector<Extension> extensions{
        _extension(GL,EXT,texture_filter_anisotropic)};
    static const std::vector<Extension> extensions300{
        _extension(GL,APPLE,flush_buffer_range),
        _extension(GL,APPLE,vertex_array_object),
        _extension(GL,ARB,color_buffer_float),
        _extension(GL,ARB,half_float_pixel),
        _extension(GL,ARB,texture_float),
        _extension(GL,ARB,depth_buffer_float),
        _extension(GL,ARB,texture_rg),
        _extension(GL,EXT,framebuffer_object),
        _extension(GL,EXT,packed_depth_stencil),
        _extension(GL,EXT,framebuffer_blit),
        _extension(GL,EXT,framebuffer_multisample),
        _extension(GL,EXT,gpu_shader4),
        _extension(GL,EXT,packed_float),
        _extension(GL,EXT,texture_array),
        _extension(GL,EXT,texture_compression_rgtc),
        _extension(GL,EXT,texture_shared_exponent),
        _extension(GL,EXT,framebuffer_sRGB),
        _extension(GL,EXT,draw_buffers2),
        _extension(GL,EXT,texture_integer),
        _extension(GL,EXT,transform_feedback),
        _extension(GL,NV,half_float),
        _extension(GL,NV,depth_buffer_float),
        _extension(GL,NV,conditional_render)};
    static const std::vector<Extension> extensions310{
        _extension(GL,ARB,texture_rectangle),
        _extension(GL,ARB,draw_instanced),
        _extension(GL,ARB,texture_buffer_object),
        _extension(GL,ARB,uniform_buffer_object),
        _extension(GL,ARB,copy_buffer),
        _extension(GL,EXT,texture_snorm),
        _extension(GL,NV,primitive_restart)};
    static const std::vector<Extension> extensions320{
        _extension(GL,ARB,geometry_shader4),
        _extension(GL,ARB,depth_clamp),
        _extension(GL,ARB,draw_elements_base_vertex),
        _extension(GL,ARB,fragment_coord_conventions),
        _extension(GL,ARB,provoking_vertex),
        _extension(GL,ARB,seamless_cube_map),
        _extension(GL,ARB,sync),
        _extension(GL,ARB,texture_multisample),
        _extension(GL,ARB,vertex_array_bgra)};
    static const std::vector<Extension> extensions330{
        _extension(GL,ARB,instanced_arrays),
        _extension(GL,ARB,blend_func_extended),
        _extension(GL,ARB,explicit_attrib_location),
        _extension(GL,ARB,occlusion_query2),
        _extension(GL,ARB,sampler_objects),
        _extension(GL,ARB,shader_bit_encoding),
        _extension(GL,ARB,texture_rgb10_a2ui),
        _extension(GL,ARB,texture_swizzle),
        _extension(GL,ARB,timer_query),
        _extension(GL,ARB,vertex_type_2_10_10_10_rev)};
    static const std::vector<Extension> extensions400{
        _extension(GL,ARB,draw_buffers_blend),
        _extension(GL,ARB,sample_shading),
        _extension(GL,ARB,texture_cube_map_array),
        _extension(GL,ARB,texture_gather),
        _extension(GL,ARB,texture_query_lod),
        _extension(GL,ARB,draw_indirect),
        _extension(GL,ARB,gpu_shader5),
        _extension(GL,ARB,gpu_shader_fp64),
        _extension(GL,ARB,shader_subroutine),
        _extension(GL,ARB,tessellation_shader),
        _extension(GL,ARB,texture_buffer_object_rgb32),
        _extension(GL,ARB,transform_feedback2),
        _extension(GL,ARB,transform_feedback3)};
    static const std::vector<Extension> extensions410{
        _extension(GL,ARB,ES2_compatibility),
        _extension(GL,ARB,get_program_binary),
        _extension(GL,ARB,separate_shader_objects),
        _extension(GL,ARB,shader_precision),
        _extension(GL,ARB,vertex_attrib_64bit),
        _extension(GL,ARB,viewport_array)};
    static const std::vector<Extension> extensions420{
        _extension(GL,ARB,texture_compression_bptc),
        _extension(GL,ARB,base_instance),
        _extension(GL,ARB,shading_language_420pack),
        _extension(GL,ARB,transform_feedback_instanced),
        _extension(GL,ARB,compressed_texture_pixel_storage),
        _extension(GL,ARB,conservative_depth),
        _extension(GL,ARB,internalformat_query),
        _extension(GL,ARB,map_buffer_alignment),
        _extension(GL,ARB,shader_atomic_counters),
        _extension(GL,ARB,shader_image_load_store),
        _extension(GL,ARB,texture_storage)};
    static const std::vector<Extension> extensions430;
    #undef _extension
    #else
    static const std::vector<Extension> extensions;
    static const std::vector<Extension> extensionsES200;
    static const std::vector<Extension> extensionsES300;
    #endif

    switch(version) {
        case Version::None:  return extensions;
        #ifndef MAGNUM_TARGET_GLES
        case Version::GL210: return empty;
        case Version::GL300: return extensions300;
        case Version::GL310: return extensions310;
        case Version::GL320: return extensions320;
        case Version::GL330: return extensions330;
        case Version::GL400: return extensions400;
        /* case Version::GLES200: */
        case Version::GL410: return extensions410;
        case Version::GL420: return extensions420;
        /* case Version::GLES300: */
        case Version::GL430: return extensions430;
        #else
        case Version::GLES200: return extensionsES200;
        case Version::GLES300: return extensionsES300;
        #endif
    }

    return empty;
}

Context* Context::_current = nullptr;

Context::Context() {
    /* Version */
    glGetIntegerv(GL_MAJOR_VERSION, &_majorVersion);
    glGetIntegerv(GL_MINOR_VERSION, &_minorVersion);
    _version = static_cast<Version>(_majorVersion*100+_minorVersion*10);

    /* Get first future (not supported) version */
    vector<Version> versions{
        #ifndef MAGNUM_TARGET_GLES
        Version::GL300,
        Version::GL310,
        Version::GL320,
        Version::GL330,
        Version::GL400,
        Version::GL410,
        Version::GL420,
        Version::GL430,
        #else
        Version::GLES200,
        Version::GLES300,
        #endif
        Version::None
    };
    size_t future = 0;
    while(versions[future] != Version::None && versions[future] < _version)
        ++future;

    /* List of extensions from future versions (extensions from current and
       previous versions should be supported automatically, so we don't need
       to check for them) */
    unordered_map<string, Extension> futureExtensions;
    for(size_t i = future; i != versions.size(); ++i)
        for(const Extension& extension: Extension::extensions(versions[i]))
            futureExtensions.insert(make_pair(extension._string, extension));

    /* Check for presence of extensions in future versions */
    #ifndef MAGNUM_TARGET_GLES
    if(isVersionSupported(Version::GL300)) {
    #else
    if(isVersionSupported(Version::GLES300)) {
    #endif
        #ifndef MAGNUM_TARGET_GLES2
        GLuint index = 0;
        const char* extension;
        while((extension = reinterpret_cast<const char*>(glGetStringi(GL_EXTENSIONS, index++)))) {
            auto found = futureExtensions.find(extension);
            if(found != futureExtensions.end()) {
                _supportedExtensions.push_back(found->second);
                extensionStatus.set(found->second._index);
            }
        }
        #endif

    /* OpenGL 2.1 / OpenGL ES 2.0 doesn't have glGetStringi() */
    } else {
        vector<string> extensions = Corrade::Utility::split(reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS)), ' ');
        for(const string& extension: extensions) {
            auto found = futureExtensions.find(extension);
            if(found != futureExtensions.end()) {
                _supportedExtensions.push_back(found->second);
                extensionStatus.set(found->second._index);
            }
        }
    }

    /* Set this context as current */
    CORRADE_ASSERT(!_current, "Context: Another context currently active", );
    _current = this;

    /* Initialize state tracker */
    _state = new Implementation::State;

    /* Initialize functionality based on current OpenGL version and extensions */
    AbstractShaderProgram::initializeContextBasedFunctionality(this);
    AbstractTexture::initializeContextBasedFunctionality(this);
    Buffer::initializeContextBasedFunctionality(this);
    #ifndef MAGNUM_TARGET_GLES
    BufferedTexture::initializeContextBasedFunctionality(this);
    #endif
    IndexedMesh::initializeContextBasedFunctionality(this);
    Mesh::initializeContextBasedFunctionality(this);
}

Context::~Context() {
    CORRADE_ASSERT(_current == this, "Context: Cannot destroy context which is not currently active", );
    delete _state;
    _current = nullptr;
}

Version Context::supportedVersion(initializer_list<Version> versions) const {
    for(auto version: versions)
        if(isVersionSupported(version)) return version;

    #ifndef MAGNUM_TARGET_GLES
    return Version::GL210;
    #else
    return Version::GLES200;
    #endif
}

}
<commit_msg>Avoid crash when glGetString(GL_EXTENSIONS) returns nullptr.<commit_after>/*
    Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz>

    This file is part of Magnum.

    Magnum is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License version 3
    only, as published by the Free Software Foundation.

    Magnum is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU Lesser General Public License version 3 for more details.
*/

#include "Context.h"

#include <string>
#include <unordered_map>
#include <Utility/Debug.h>

#include "AbstractShaderProgram.h"
#include "AbstractTexture.h"
#include "Buffer.h"
#include "BufferedTexture.h"
#include "Extensions.h"
#include "IndexedMesh.h"
#include "Mesh.h"
#include "Implementation/State.h"

using namespace std;

namespace Magnum {

const std::vector<Extension>& Extension::extensions(Version version) {
    #define _extension(prefix, vendor, extension)                           \
        {Extensions::prefix::vendor::extension::Index, Extensions::prefix::vendor::extension::requiredVersion(), Extensions::prefix::vendor::extension::coreVersion(), Extensions::prefix::vendor::extension::string()}
    static const std::vector<Extension> empty;
    #ifndef MAGNUM_TARGET_GLES
    static const std::vector<Extension> extensions{
        _extension(GL,EXT,texture_filter_anisotropic)};
    static const std::vector<Extension> extensions300{
        _extension(GL,APPLE,flush_buffer_range),
        _extension(GL,APPLE,vertex_array_object),
        _extension(GL,ARB,color_buffer_float),
        _extension(GL,ARB,half_float_pixel),
        _extension(GL,ARB,texture_float),
        _extension(GL,ARB,depth_buffer_float),
        _extension(GL,ARB,texture_rg),
        _extension(GL,EXT,framebuffer_object),
        _extension(GL,EXT,packed_depth_stencil),
        _extension(GL,EXT,framebuffer_blit),
        _extension(GL,EXT,framebuffer_multisample),
        _extension(GL,EXT,gpu_shader4),
        _extension(GL,EXT,packed_float),
        _extension(GL,EXT,texture_array),
        _extension(GL,EXT,texture_compression_rgtc),
        _extension(GL,EXT,texture_shared_exponent),
        _extension(GL,EXT,framebuffer_sRGB),
        _extension(GL,EXT,draw_buffers2),
        _extension(GL,EXT,texture_integer),
        _extension(GL,EXT,transform_feedback),
        _extension(GL,NV,half_float),
        _extension(GL,NV,depth_buffer_float),
        _extension(GL,NV,conditional_render)};
    static const std::vector<Extension> extensions310{
        _extension(GL,ARB,texture_rectangle),
        _extension(GL,ARB,draw_instanced),
        _extension(GL,ARB,texture_buffer_object),
        _extension(GL,ARB,uniform_buffer_object),
        _extension(GL,ARB,copy_buffer),
        _extension(GL,EXT,texture_snorm),
        _extension(GL,NV,primitive_restart)};
    static const std::vector<Extension> extensions320{
        _extension(GL,ARB,geometry_shader4),
        _extension(GL,ARB,depth_clamp),
        _extension(GL,ARB,draw_elements_base_vertex),
        _extension(GL,ARB,fragment_coord_conventions),
        _extension(GL,ARB,provoking_vertex),
        _extension(GL,ARB,seamless_cube_map),
        _extension(GL,ARB,sync),
        _extension(GL,ARB,texture_multisample),
        _extension(GL,ARB,vertex_array_bgra)};
    static const std::vector<Extension> extensions330{
        _extension(GL,ARB,instanced_arrays),
        _extension(GL,ARB,blend_func_extended),
        _extension(GL,ARB,explicit_attrib_location),
        _extension(GL,ARB,occlusion_query2),
        _extension(GL,ARB,sampler_objects),
        _extension(GL,ARB,shader_bit_encoding),
        _extension(GL,ARB,texture_rgb10_a2ui),
        _extension(GL,ARB,texture_swizzle),
        _extension(GL,ARB,timer_query),
        _extension(GL,ARB,vertex_type_2_10_10_10_rev)};
    static const std::vector<Extension> extensions400{
        _extension(GL,ARB,draw_buffers_blend),
        _extension(GL,ARB,sample_shading),
        _extension(GL,ARB,texture_cube_map_array),
        _extension(GL,ARB,texture_gather),
        _extension(GL,ARB,texture_query_lod),
        _extension(GL,ARB,draw_indirect),
        _extension(GL,ARB,gpu_shader5),
        _extension(GL,ARB,gpu_shader_fp64),
        _extension(GL,ARB,shader_subroutine),
        _extension(GL,ARB,tessellation_shader),
        _extension(GL,ARB,texture_buffer_object_rgb32),
        _extension(GL,ARB,transform_feedback2),
        _extension(GL,ARB,transform_feedback3)};
    static const std::vector<Extension> extensions410{
        _extension(GL,ARB,ES2_compatibility),
        _extension(GL,ARB,get_program_binary),
        _extension(GL,ARB,separate_shader_objects),
        _extension(GL,ARB,shader_precision),
        _extension(GL,ARB,vertex_attrib_64bit),
        _extension(GL,ARB,viewport_array)};
    static const std::vector<Extension> extensions420{
        _extension(GL,ARB,texture_compression_bptc),
        _extension(GL,ARB,base_instance),
        _extension(GL,ARB,shading_language_420pack),
        _extension(GL,ARB,transform_feedback_instanced),
        _extension(GL,ARB,compressed_texture_pixel_storage),
        _extension(GL,ARB,conservative_depth),
        _extension(GL,ARB,internalformat_query),
        _extension(GL,ARB,map_buffer_alignment),
        _extension(GL,ARB,shader_atomic_counters),
        _extension(GL,ARB,shader_image_load_store),
        _extension(GL,ARB,texture_storage)};
    static const std::vector<Extension> extensions430;
    #undef _extension
    #else
    static const std::vector<Extension> extensions;
    static const std::vector<Extension> extensionsES200;
    static const std::vector<Extension> extensionsES300;
    #endif

    switch(version) {
        case Version::None:  return extensions;
        #ifndef MAGNUM_TARGET_GLES
        case Version::GL210: return empty;
        case Version::GL300: return extensions300;
        case Version::GL310: return extensions310;
        case Version::GL320: return extensions320;
        case Version::GL330: return extensions330;
        case Version::GL400: return extensions400;
        /* case Version::GLES200: */
        case Version::GL410: return extensions410;
        case Version::GL420: return extensions420;
        /* case Version::GLES300: */
        case Version::GL430: return extensions430;
        #else
        case Version::GLES200: return extensionsES200;
        case Version::GLES300: return extensionsES300;
        #endif
    }

    return empty;
}

Context* Context::_current = nullptr;

Context::Context() {
    /* Version */
    glGetIntegerv(GL_MAJOR_VERSION, &_majorVersion);
    glGetIntegerv(GL_MINOR_VERSION, &_minorVersion);
    _version = static_cast<Version>(_majorVersion*100+_minorVersion*10);

    /* Get first future (not supported) version */
    vector<Version> versions{
        #ifndef MAGNUM_TARGET_GLES
        Version::GL300,
        Version::GL310,
        Version::GL320,
        Version::GL330,
        Version::GL400,
        Version::GL410,
        Version::GL420,
        Version::GL430,
        #else
        Version::GLES200,
        Version::GLES300,
        #endif
        Version::None
    };
    size_t future = 0;
    while(versions[future] != Version::None && versions[future] < _version)
        ++future;

    /* List of extensions from future versions (extensions from current and
       previous versions should be supported automatically, so we don't need
       to check for them) */
    unordered_map<string, Extension> futureExtensions;
    for(size_t i = future; i != versions.size(); ++i)
        for(const Extension& extension: Extension::extensions(versions[i]))
            futureExtensions.insert(make_pair(extension._string, extension));

    /* Check for presence of extensions in future versions */
    #ifndef MAGNUM_TARGET_GLES
    if(isVersionSupported(Version::GL300)) {
    #else
    if(isVersionSupported(Version::GLES300)) {
    #endif
        #ifndef MAGNUM_TARGET_GLES2
        GLuint index = 0;
        const char* extension;
        while((extension = reinterpret_cast<const char*>(glGetStringi(GL_EXTENSIONS, index++)))) {
            auto found = futureExtensions.find(extension);
            if(found != futureExtensions.end()) {
                _supportedExtensions.push_back(found->second);
                extensionStatus.set(found->second._index);
            }
        }
        #endif

    /* OpenGL 2.1 / OpenGL ES 2.0 doesn't have glGetStringi() */
    } else {
        /* Don't crash when glGetString() returns nullptr */
        const char* e = reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS));
        if(e) {
            vector<string> extensions = Corrade::Utility::split(e, ' ');
            for(const string& extension: extensions) {
                auto found = futureExtensions.find(extension);
                if(found != futureExtensions.end()) {
                    _supportedExtensions.push_back(found->second);
                    extensionStatus.set(found->second._index);
                }
            }
        }
    }

    /* Set this context as current */
    CORRADE_ASSERT(!_current, "Context: Another context currently active", );
    _current = this;

    /* Initialize state tracker */
    _state = new Implementation::State;

    /* Initialize functionality based on current OpenGL version and extensions */
    AbstractShaderProgram::initializeContextBasedFunctionality(this);
    AbstractTexture::initializeContextBasedFunctionality(this);
    Buffer::initializeContextBasedFunctionality(this);
    #ifndef MAGNUM_TARGET_GLES
    BufferedTexture::initializeContextBasedFunctionality(this);
    #endif
    IndexedMesh::initializeContextBasedFunctionality(this);
    Mesh::initializeContextBasedFunctionality(this);
}

Context::~Context() {
    CORRADE_ASSERT(_current == this, "Context: Cannot destroy context which is not currently active", );
    delete _state;
    _current = nullptr;
}

Version Context::supportedVersion(initializer_list<Version> versions) const {
    for(auto version: versions)
        if(isVersionSupported(version)) return version;

    #ifndef MAGNUM_TARGET_GLES
    return Version::GL210;
    #else
    return Version::GLES200;
    #endif
}

}
<|endoftext|>


<commit_before>/*
  Copyright (c) 2011 Neevarp Yhtroom

  Permission is hereby granted, free of charge, to any person obtaining
  a copy of this software and associated documentation files (the
  "Software"), to deal in the Software without restriction, including
  without limitation the rights to use, copy, modify, merge, publish,
  distribute, sublicense, and/or sell copies of the Software, and to
  permit persons to whom the Software is furnished to do so, subject to
  the following conditions:

  The above copyright notice and this permission notice shall be
  included in all copies or substantial portions of the Software.

  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

#include <fstream>
#include "CsvFile.h"

using std::vector;
using std::ifstream;
using std::ofstream;
using std::endl;

namespace lepcpplib {
CsvFile::CsvFile(const String& filename)
  : filename_(filename), separator_(',')
{
}

CsvFile::CsvFile(const String& filename, char separator)
  : filename_(filename), separator_(separator)
{
}

CsvFile::~CsvFile()
{
}

bool CsvFile::Load()
{
  bool parsable = false;
  char buffer[10];
  String line;
  ifstream file(filename_.toCharArray(), ifstream::binary);

  while((!file.eof()) && (file.good())) {
    file.read(buffer, sizeof(buffer));
    int pend = file.gcount();
    parsable = true;
    int pbegin = 0;
    int pcurrent = 0;

    while (pcurrent < pend) {
      if (buffer[pcurrent] == '\n') {

        String part(buffer + pbegin, (pcurrent - pbegin + 1));
        line += part;
        int l = line.length();

        if ((l == 1) && (line.charAt(0) == '\n')) {
          // empty line. ignore.
          line = "";
        }
        else if ((l == 2) && (line.charAt(0) == '\r') && (line.charAt(1) == '\n')) {
          // empty line. ignore.
          line = "";
        }
        else if ((l > 2) &&
            (line.charAt(l - 2) == '\r') &&
            (line.charAt(l - 1) == '\n')) {
              // crlf delimited line. parse it out.
              line = line.substring(0, l - 3);
        }
        else if ((l > 1) &&
            // cr delimited line. parse it out.
            (line.charAt(l - 1) == '\n')) {
              line = line.substring(0, l - 2);
        }

        if (line.length() > 0) {
          vector<String> row;
          line.tokenize(separator_, row);
          records_.push_back(row);
          line = "";
        }

        pbegin = pcurrent + 1;
      }

      pcurrent++;
    }

    // if no delimiter was found in this pass, store the
    // residue in line so that it gets appended with
    // the new set of characters read.
    if (pbegin < pcurrent) {
      String part(buffer + pbegin, pend - pbegin);
      line = line + part;
    }
  }

  return parsable;
}

void CsvFile::Save()
{
  ofstream file(filename_.toCharArray());
  for (int i = 0; i < records_.size(); i++) {
    vector<String>& row = records_[i];
    for (int j = 0; j < row.size(); j++) {
      if (row[j].length()) {
        file << row[j].toCharArray();
      }
      else {
        file << "";
      }

      // no separator for last column.
      if (j != row.size() - 1) {
        file << separator_;
      }
    }

    file << endl;
  }

  file << endl;
}

void CsvFile::Append(const std::vector<String>& record)
{
  records_.push_back(record);
}

void CsvFile::Insert(const std::vector<String>& record, int row)
{
  if (row > 0) {
    if (row > records_.size()) {
      int new_entries = row - records_.size();
      vector<String> blank;
      blank.insert(blank.begin(), record.size(), "");

      for (int i = 0; i < new_entries; i++) {
        records_.push_back(blank);
      }
    }

    records_.insert(records_.begin() + row, record);
  }
}

void CsvFile::Remove(int row)
{
  if ((row < records_.size()) && (row >= 0)) {
    vector<vector<String>>::iterator it = records_.begin();
    records_.erase(it + row);
  }
}

String CsvFile::ValueOf(int row, int column)
{
  if ((row < records_.size()) && (column < records_[row].size())) {
    return (records_[row][column]);
  }
  else {
    return "";
  }
}

const String& CsvFile::filename()
{
  return filename_;
}

void CsvFile::set_filename(const String& filename)
{
  filename_ = filename;
}

int CsvFile::RowCount()
{
  return records_.size();
}

int CsvFile::ColumnCount()
{
  int result = 0;

  if (records_.size() > 0) {
    // csv files should have identical column count for all rows.
    result = records_[0].size();
  }

  return result;
}
}
<commit_msg>cr, crlf, lf?<commit_after>/*
  Copyright (c) 2011 Neevarp Yhtroom

  Permission is hereby granted, free of charge, to any person obtaining
  a copy of this software and associated documentation files (the
  "Software"), to deal in the Software without restriction, including
  without limitation the rights to use, copy, modify, merge, publish,
  distribute, sublicense, and/or sell copies of the Software, and to
  permit persons to whom the Software is furnished to do so, subject to
  the following conditions:

  The above copyright notice and this permission notice shall be
  included in all copies or substantial portions of the Software.

  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

#include <fstream>
#include "CsvFile.h"

using std::vector;
using std::ifstream;
using std::ofstream;
using std::endl;

namespace lepcpplib {
CsvFile::CsvFile(const String& filename)
  : filename_(filename), separator_(',')
{
}

CsvFile::CsvFile(const String& filename, char separator)
  : filename_(filename), separator_(separator)
{
}

CsvFile::~CsvFile()
{
}

bool CsvFile::Load()
{
  bool parsable = false;
  char buffer[10];
  String line;
  ifstream file(filename_.toCharArray(), ifstream::binary);

  while((!file.eof()) && (file.good())) {
    file.read(buffer, sizeof(buffer));
    int pend = file.gcount();
    parsable = true;
    int pbegin = 0;
    int pcurrent = 0;

    while (pcurrent < pend) {
      if (buffer[pcurrent] == '\n') {

        String part(buffer + pbegin, (pcurrent - pbegin + 1));
        line += part;
        int l = line.length();

        if ((l == 1) && (line.charAt(0) == '\n')) {
          // empty line. ignore.
          line = "";
        }
        else if ((l == 2) && (line.charAt(0) == '\r') && (line.charAt(1) == '\n')) {
          // empty line. ignore.
          line = "";
        }
        else if ((l > 2) &&
            (line.charAt(l - 2) == '\r') &&
            (line.charAt(l - 1) == '\n')) {
              // crlf delimited line. parse it out.
              line = line.substring(0, l - 3);
        }
        else if ((l > 1) &&
            // cr delimited line. parse it out.
            (line.charAt(l - 1) == '\n')) {
              line = line.substring(0, l - 2);
        }

        if (line.length() > 0) {
          vector<String> row;
          line.tokenize(separator_, row);
          records_.push_back(row);
          line = "";
        }

        pbegin = pcurrent + 1;
      }

      pcurrent++;
    }

    // if no delimiter was found in this pass, store the
    // residue in line so that it gets appended with
    // the new set of characters read.
    if (pbegin < pcurrent) {
      String part(buffer + pbegin, pend - pbegin);
      line = line + part;
    }
  }

  return parsable;
}

void CsvFile::Save()
{
  ofstream file(filename_.toCharArray());
  for (int i = 0; i < records_.size(); i++) {
    vector<String>& row = records_[i];
    for (int j = 0; j < row.size(); j++) {
      if (row[j].length()) {
        file << row[j].toCharArray();
      }
      else {
        file << "";
      }

      // no separator for last column.
      if (j != row.size() - 1) {
        file << separator_;
      }
    }

    file << endl;
  }

  file << endl;
}

void CsvFile::Append(const std::vector<String>& record)
{
  records_.push_back(record);
}

void CsvFile::Insert(const std::vector<String>& record, int row)
{
  if (row > 0) {
    if (row > records_.size()) {
      int new_entries = row - records_.size();
      vector<String> blank;
      blank.insert(blank.begin(), record.size(), "");

      for (int i = 0; i < new_entries; i++) {
        records_.push_back(blank);
      }
    }

    records_.insert(records_.begin() + row, record);
  }
}

void CsvFile::Remove(int row)
{
  if ((row < records_.size()) && (row >= 0)) {
    vector<vector<String>>::iterator it = records_.begin();
    records_.erase(it + row);
  }
}

String CsvFile::ValueOf(int row, int column)
{
  if ((row < records_.size()) && (column < records_[row].size())) {
    return (records_[row][column]);
  }
  else {
    return "";
  }
}

const String& CsvFile::filename()
{
  return filename_;
}

void CsvFile::set_filename(const String& filename)
{
  filename_ = filename;
}

int CsvFile::RowCount()
{
  return records_.size();
}

int CsvFile::ColumnCount()
{
  int result = 0;

  if (records_.size() > 0) {
    // csv files should have identical column count for all rows.
    result = records_[0].size();
  }

  return result;
}
} // namespace lepcpplib
<|endoftext|>


<commit_before>
/*
 *  Stream.cpp
 *  sfeMovie project
 *
 *  Copyright (C) 2010-2014 Lucas Soltic
 *  lucas.soltic@orange.fr
 *
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 *
 */

extern "C"
{
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
#include <libswscale/swscale.h>
}

#include "Demuxer.hpp"
#include "VideoStream.hpp"
#include "AudioStream.hpp"
#include "SubtitleStream.hpp"
#include "Threads.hpp"
#include "Log.hpp"
#include "Utilities.hpp"
#include <iostream>
#include <stdexcept>

namespace sfe {
	std::list<Demuxer::DemuxerInfo> Demuxer::g_availableDemuxers;
	std::list<Demuxer::DecoderInfo> Demuxer::g_availableDecoders;

	static void loadFFmpeg(void)
	{
		ONCE(av_register_all());
		ONCE(avcodec_register_all());
	}

	static MediaType AVMediaTypeToMediaType(AVMediaType type)
	{
		switch (type) {
			case AVMEDIA_TYPE_AUDIO:	return MEDIA_TYPE_AUDIO;
			case AVMEDIA_TYPE_SUBTITLE:	return MEDIA_TYPE_SUBTITLE;
			case AVMEDIA_TYPE_VIDEO:	return MEDIA_TYPE_VIDEO;
			default:					return MEDIA_TYPE_UNKNOWN;
		}
	}

	const std::list<Demuxer::DemuxerInfo>& Demuxer::getAvailableDemuxers(void)
	{
		AVInputFormat* demuxer = NULL;
		loadFFmpeg();

		if (g_availableDemuxers.empty()) {
			while (NULL != (demuxer = av_iformat_next(demuxer))) {
				DemuxerInfo info = {
					std::string(demuxer->name),
					std::string(demuxer->long_name)
				};

				g_availableDemuxers.push_back(info);
			}
		}

		return g_availableDemuxers;
	}

	const std::list<Demuxer::DecoderInfo>& Demuxer::getAvailableDecoders(void)
	{
		AVCodecRef codec = NULL;
		loadFFmpeg();

		if (g_availableDecoders.empty()) {
			while (NULL != (codec = av_codec_next(codec))) {
				DecoderInfo info = {
					avcodec_get_name(codec->id),
					codec->long_name,
					AVMediaTypeToMediaType(codec->type)
				};

				g_availableDecoders.push_back(info);
			}
		}

		return g_availableDecoders;
	}

	Demuxer::Demuxer(const std::string& sourceFile, Timer& timer) :
	m_avFormatCtx(NULL),
	m_eofReached(false),
	m_streams(),
	m_ignoredStreams(),
	m_synchronized(),
	m_timer(timer)
	{
		CHECK(sourceFile.size(), "Demuxer::Demuxer() - invalid argument: sourceFile");

		int err = 0;

		// Load all the decoders
		loadFFmpeg();

		// Open the movie file
		err = avformat_open_input(&m_avFormatCtx, sourceFile.c_str(), NULL, NULL);
		CHECK0(err, "Demuxer::Demuxer() - error while opening media: " + sourceFile);
		CHECK(m_avFormatCtx, "Demuxer() - inconsistency: media context cannot be null");

		// Read the general movie informations
		err = avformat_find_stream_info(m_avFormatCtx, NULL);
		CHECK0(err, "Demuxer::Demuxer() - error while retreiving media information");

		// Find all interesting streams
		for (int i = 0; i < m_avFormatCtx->nb_streams; i++) {
			AVStreamRef ffstream = m_avFormatCtx->streams[i];

			try {
				switch (ffstream->codec->codec_type) {
//					case AVMEDIA_TYPE_VIDEO:
//						m_streams[ffstream->index] = new VideoStream(ffstream, *this, timer);
//						sfeLogDebug("Loaded " + avcodec_get_name(ffstream->codec->codec_id) + " video stream");
//						break;

					case AVMEDIA_TYPE_AUDIO:
						m_streams[ffstream->index] = new AudioStream(ffstream, *this, timer);
						sfeLogDebug("Loaded " + avcodec_get_name(ffstream->codec->codec_id) + " audio stream");
						break;

						/** TODO
						 case AVMEDIA_TYPE_SUBTITLE:
						 m_streams.push_back(new SubtitleStream(ffstream));
						 break;
						 */

					default:
						m_ignoredStreams[ffstream->index] = std::string(std::string(av_get_media_type_string(ffstream->codec->codec_type)) + "/" + avcodec_get_name(ffstream->codec->codec_id));
						sfeLogWarning(m_ignoredStreams[ffstream->index] + "' stream ignored");
						break;
				}
			} catch (std::runtime_error& e) {
				std::cerr << "Demuxer::Demuxer() - " << e.what() << std::endl;
			}
		}
	}

	Demuxer::~Demuxer(void)
	{
		if (m_timer.getStatus() != Timer::Stopped)
			m_timer.stop();

		while (m_streams.size()) {
			delete m_streams.begin()->second;
			m_streams.erase(m_streams.begin());
		}

		if (m_avFormatCtx) {
			avformat_close_input(&m_avFormatCtx);
		}
	}

	const std::map<int, Stream*>& Demuxer::getStreams(void) const
	{
		return m_streams;
	}

	std::set<Stream*> Demuxer::getStreamsOfType(MediaType type) const
	{
		std::set<Stream*> streamSet;

		std::map<int, Stream*>::const_iterator it;

		for (it = m_streams.begin(); it != m_streams.end(); it++) {
			if (it->second->getStreamKind() == type)
				streamSet.insert(it->second);
		}

		return streamSet;
	}

	void Demuxer::feedStream(Stream& stream)
	{
		sf::Lock l(m_synchronized);

//		sfeLogDebug(Threads::currentThreadName());

		while (!didReachEndOfFile() && stream.needsMoreData()) {
			AVPacketRef pkt = readPacket();

			if (!pkt) {
				m_eofReached = true;
			} else {
				if (!distributePacket(pkt)) {
					sfeLogWarning(m_ignoredStreams[pkt->stream_index] + " packet not handled and dropped");
					av_free_packet(pkt);
					av_free(pkt);
				}
			}
		}
	}

	void Demuxer::updateVideoStreams(void)
	{
		std::set<Stream*> streams = getStreamsOfType(MEDIA_TYPE_VIDEO);
		std::set<Stream*>::iterator it;

		for (it = streams.begin();it != streams.end(); it++) {
			VideoStream* vStream = dynamic_cast<VideoStream*>(*it);
			CHECK(vStream, "Demuxer::updateVideoStreams() - got non video streams");

			vStream->updateTexture();
		}
	}

	bool Demuxer::didReachEndOfFile(void) const
	{
		return m_eofReached;
	}

	AVPacketRef Demuxer::readPacket(void)
	{
		sf::Lock l(m_synchronized);
//		sfeLogDebug(Threads::currentThreadName());

		AVPacket *pkt = NULL;
		int err = 0;

		pkt = (AVPacket *)av_malloc(sizeof(*pkt));
		CHECK(pkt, "Demuxer::readPacket() - out of memory");
		av_init_packet(pkt);

		err = av_read_frame(m_avFormatCtx, pkt);

		if (err < 0) {
			av_free_packet(pkt);
			av_free(pkt);
			pkt = NULL;
		}

		return pkt;
	}

	bool Demuxer::distributePacket(AVPacketRef packet)
	{
		sf::Lock l(m_synchronized);
		CHECK(packet, "Demuxer::distributePacket() - invalid argument");
//		sfeLogDebug(Threads::currentThreadName());

		bool result = false;
		std::map<int, Stream*>::iterator it = m_streams.find(packet->stream_index);

		if (it != m_streams.end()) {
			it->second->pushEncodedData(packet);
			result = true;
		}

		return result;
	}

	void Demuxer::requestMoreData(Stream& starvingStream)
	{
		sf::Lock l(m_synchronized);
//		sfeLogDebug(Threads::currentThreadName());

		feedStream(starvingStream);
	}
}
<commit_msg>#34 Enable video streams<commit_after>
/*
 *  Stream.cpp
 *  sfeMovie project
 *
 *  Copyright (C) 2010-2014 Lucas Soltic
 *  lucas.soltic@orange.fr
 *
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 *
 */

extern "C"
{
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
#include <libswscale/swscale.h>
}

#include "Demuxer.hpp"
#include "VideoStream.hpp"
#include "AudioStream.hpp"
#include "SubtitleStream.hpp"
#include "Threads.hpp"
#include "Log.hpp"
#include "Utilities.hpp"
#include <iostream>
#include <stdexcept>

namespace sfe {
	std::list<Demuxer::DemuxerInfo> Demuxer::g_availableDemuxers;
	std::list<Demuxer::DecoderInfo> Demuxer::g_availableDecoders;

	static void loadFFmpeg(void)
	{
		ONCE(av_register_all());
		ONCE(avcodec_register_all());
	}

	static MediaType AVMediaTypeToMediaType(AVMediaType type)
	{
		switch (type) {
			case AVMEDIA_TYPE_AUDIO:	return MEDIA_TYPE_AUDIO;
			case AVMEDIA_TYPE_SUBTITLE:	return MEDIA_TYPE_SUBTITLE;
			case AVMEDIA_TYPE_VIDEO:	return MEDIA_TYPE_VIDEO;
			default:					return MEDIA_TYPE_UNKNOWN;
		}
	}

	const std::list<Demuxer::DemuxerInfo>& Demuxer::getAvailableDemuxers(void)
	{
		AVInputFormat* demuxer = NULL;
		loadFFmpeg();

		if (g_availableDemuxers.empty()) {
			while (NULL != (demuxer = av_iformat_next(demuxer))) {
				DemuxerInfo info = {
					std::string(demuxer->name),
					std::string(demuxer->long_name)
				};

				g_availableDemuxers.push_back(info);
			}
		}

		return g_availableDemuxers;
	}

	const std::list<Demuxer::DecoderInfo>& Demuxer::getAvailableDecoders(void)
	{
		AVCodecRef codec = NULL;
		loadFFmpeg();

		if (g_availableDecoders.empty()) {
			while (NULL != (codec = av_codec_next(codec))) {
				DecoderInfo info = {
					avcodec_get_name(codec->id),
					codec->long_name,
					AVMediaTypeToMediaType(codec->type)
				};

				g_availableDecoders.push_back(info);
			}
		}

		return g_availableDecoders;
	}

	Demuxer::Demuxer(const std::string& sourceFile, Timer& timer) :
	m_avFormatCtx(NULL),
	m_eofReached(false),
	m_streams(),
	m_ignoredStreams(),
	m_synchronized(),
	m_timer(timer)
	{
		CHECK(sourceFile.size(), "Demuxer::Demuxer() - invalid argument: sourceFile");

		int err = 0;

		// Load all the decoders
		loadFFmpeg();

		// Open the movie file
		err = avformat_open_input(&m_avFormatCtx, sourceFile.c_str(), NULL, NULL);
		CHECK0(err, "Demuxer::Demuxer() - error while opening media: " + sourceFile);
		CHECK(m_avFormatCtx, "Demuxer() - inconsistency: media context cannot be null");

		// Read the general movie informations
		err = avformat_find_stream_info(m_avFormatCtx, NULL);
		CHECK0(err, "Demuxer::Demuxer() - error while retreiving media information");

		// Find all interesting streams
		for (int i = 0; i < m_avFormatCtx->nb_streams; i++) {
			AVStreamRef ffstream = m_avFormatCtx->streams[i];

			try {
				switch (ffstream->codec->codec_type) {
					case AVMEDIA_TYPE_VIDEO:
						m_streams[ffstream->index] = new VideoStream(ffstream, *this, timer);
						sfeLogDebug("Loaded " + avcodec_get_name(ffstream->codec->codec_id) + " video stream");
						break;

					case AVMEDIA_TYPE_AUDIO:
						m_streams[ffstream->index] = new AudioStream(ffstream, *this, timer);
						sfeLogDebug("Loaded " + avcodec_get_name(ffstream->codec->codec_id) + " audio stream");
						break;

						/** TODO
						 case AVMEDIA_TYPE_SUBTITLE:
						 m_streams.push_back(new SubtitleStream(ffstream));
						 break;
						 */

					default:
						m_ignoredStreams[ffstream->index] = std::string(std::string(av_get_media_type_string(ffstream->codec->codec_type)) + "/" + avcodec_get_name(ffstream->codec->codec_id));
						sfeLogWarning(m_ignoredStreams[ffstream->index] + "' stream ignored");
						break;
				}
			} catch (std::runtime_error& e) {
				std::cerr << "Demuxer::Demuxer() - " << e.what() << std::endl;
			}
		}
	}

	Demuxer::~Demuxer(void)
	{
		if (m_timer.getStatus() != Timer::Stopped)
			m_timer.stop();

		while (m_streams.size()) {
			delete m_streams.begin()->second;
			m_streams.erase(m_streams.begin());
		}

		if (m_avFormatCtx) {
			avformat_close_input(&m_avFormatCtx);
		}
	}

	const std::map<int, Stream*>& Demuxer::getStreams(void) const
	{
		return m_streams;
	}

	std::set<Stream*> Demuxer::getStreamsOfType(MediaType type) const
	{
		std::set<Stream*> streamSet;

		std::map<int, Stream*>::const_iterator it;

		for (it = m_streams.begin(); it != m_streams.end(); it++) {
			if (it->second->getStreamKind() == type)
				streamSet.insert(it->second);
		}

		return streamSet;
	}

	void Demuxer::feedStream(Stream& stream)
	{
		sf::Lock l(m_synchronized);

//		sfeLogDebug(Threads::currentThreadName());

		while (!didReachEndOfFile() && stream.needsMoreData()) {
			AVPacketRef pkt = readPacket();

			if (!pkt) {
				m_eofReached = true;
			} else {
				if (!distributePacket(pkt)) {
					sfeLogWarning(m_ignoredStreams[pkt->stream_index] + " packet not handled and dropped");
					av_free_packet(pkt);
					av_free(pkt);
				}
			}
		}
	}

	void Demuxer::updateVideoStreams(void)
	{
		std::set<Stream*> streams = getStreamsOfType(MEDIA_TYPE_VIDEO);
		std::set<Stream*>::iterator it;

		for (it = streams.begin();it != streams.end(); it++) {
			VideoStream* vStream = dynamic_cast<VideoStream*>(*it);
			CHECK(vStream, "Demuxer::updateVideoStreams() - got non video streams");

			vStream->updateTexture();
		}
	}

	bool Demuxer::didReachEndOfFile(void) const
	{
		return m_eofReached;
	}

	AVPacketRef Demuxer::readPacket(void)
	{
		sf::Lock l(m_synchronized);
//		sfeLogDebug(Threads::currentThreadName());

		AVPacket *pkt = NULL;
		int err = 0;

		pkt = (AVPacket *)av_malloc(sizeof(*pkt));
		CHECK(pkt, "Demuxer::readPacket() - out of memory");
		av_init_packet(pkt);

		err = av_read_frame(m_avFormatCtx, pkt);

		if (err < 0) {
			av_free_packet(pkt);
			av_free(pkt);
			pkt = NULL;
		}

		return pkt;
	}

	bool Demuxer::distributePacket(AVPacketRef packet)
	{
		sf::Lock l(m_synchronized);
		CHECK(packet, "Demuxer::distributePacket() - invalid argument");
//		sfeLogDebug(Threads::currentThreadName());

		bool result = false;
		std::map<int, Stream*>::iterator it = m_streams.find(packet->stream_index);

		if (it != m_streams.end()) {
			it->second->pushEncodedData(packet);
			result = true;
		}

		return result;
	}

	void Demuxer::requestMoreData(Stream& starvingStream)
	{
		sf::Lock l(m_synchronized);
//		sfeLogDebug(Threads::currentThreadName());

		feedStream(starvingStream);
	}
}
<|endoftext|>


<commit_before>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2014.  All rights reserved
 */
#include    "Stroika/Frameworks/StroikaPreComp.h"

#include    <mutex>
#include    <iostream>

#include    "Stroika/Foundation/Characters/Format.h"
#include    "Stroika/Foundation/Execution/CommandLine.h"
#include    "Stroika/Foundation/Execution/WaitableEvent.h"
#include    "Stroika/Foundation/Memory/Optional.h"
#include    "Stroika/Foundation/IO/Network/HTTP/Headers.h"
#include    "Stroika/Foundation/IO/Network/LinkMonitor.h"
#include    "Stroika/Foundation/IO/Network/Listener.h"
#include    "Stroika/Foundation/Streams/iostream/BinaryInputStreamFromIStreamAdapter.h"
#include    "Stroika/Frameworks/UPnP/SSDP/Server/BasicServer.h"
#include    "Stroika/Frameworks/WebServer/ConnectionManager.h"

using   namespace std;

using   namespace Stroika::Foundation;
using   namespace Stroika::Foundation::IO;
using   namespace Stroika::Foundation::IO::Network;
using   namespace Stroika::Frameworks;
using   namespace Stroika::Frameworks::UPnP;
using   namespace Stroika::Frameworks::UPnP::SSDP;
using   namespace Stroika::Frameworks::WebServer;

using   Characters::String;
using   Containers::Sequence;
using   Memory::Optional;
using   Server::BasicServer;

namespace {
    struct WebServerForDeviceDescription_ {

        WebServerForDeviceDescription_ (uint16_t webServerPortNumber, const Device& d, const DeviceDescription& dd)
            : fListener ()
        {
            auto onConnect = [d, dd](Socket s) {
                Execution::Thread runConnectionOnAnotherThread ([s, d, dd]() {
                    // If the URLs are served locally, you may want to update the URL based on
                    // IO::Network::GetPrimaryInternetAddress ()
                    Memory::BLOB deviceDescription  =   Stroika::Frameworks::UPnP::Serialize (d, dd);
                    // now read
                    Connection conn (s);
                    conn.ReadHeaders ();    // bad API. Must rethink...
                    conn.GetResponse ().AddHeader (IO::Network::HTTP::HeaderName::kServer, L"stroika-ssdp-server-demo");
                    conn.GetResponse ().write (deviceDescription.begin (), deviceDescription.end ());
                    conn.GetResponse ().SetContentType (DataExchange::PredefinedInternetMediaType::XML_CT ());
                    conn.GetResponse ().End ();
                });
                runConnectionOnAnotherThread.SetThreadName (L"Connection Thread");  // SHOULD use a fancier name (connection#)
                runConnectionOnAnotherThread.Start ();
                //runConnectionOnAnotherThread.WaitForDone ();    // maybe save these in connection mgr so we can force them all shut down...
            };
            fListener = Optional<Listener> (Listener (SocketAddress (Network::V4::kAddrAny, webServerPortNumber), onConnect));
        }

        Optional<Listener>    fListener;
    };
}

int main (int argc, const char* argv[])
{
    try {
        uint16_t    portForOurWS = 8080;

        Device  d;
        d.fLocation.SetPortNumber (portForOurWS);
        d.fServer = L"unix/5.1 UPnP/1.0 MyProduct/1.0";     // @todo wrong - to be fixed
        d.fDeviceID = UPnP::MungePrimaryMacAddrIntoBaseDeviceID (L"315CAAE0-1335-57BF-A178-24C9EE756627");

        DeviceDescription   deviceInfo;
        deviceInfo.fPresentationURL = URL (L"http://www.sophists.com/");
        deviceInfo.fDeviceType = L"urn:sophists.com:device:deviceType:1.0";
        deviceInfo.fManufactureName = L"Sophist Solutions, Inc.";
        deviceInfo.fFriendlyName = L"Sophist Solutions fake device";
        deviceInfo.fManufacturingURL = URL (L"http://www.sophists.com/");
        deviceInfo.fModelDescription = L"long user-friendly title";
        deviceInfo.fModelName = L"model name";
        deviceInfo.fModelNumber = L"model number";
        deviceInfo.fModelURL = URL (L"http://www.sophists.com/");
        deviceInfo.fSerialNumber = L"manufacturer's serial number";

        WebServerForDeviceDescription_  deviceWS (portForOurWS, d, deviceInfo);
        BasicServer b (d, BasicServer::FrequencyInfo ());
        Execution::WaitableEvent (Execution::WaitableEvent::eAutoReset).Wait ();    // wait forever - til user hits ctrl-c
    }
    catch (...) {
        cerr << "Exception - terminating..." << endl;
        return EXIT_FAILURE;
    }
    return EXIT_SUCCESS;
}
<commit_msg>tweak ssdp server demo to use UPnP::SSDP::MakeServerHeaderValue ()<commit_after>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2014.  All rights reserved
 */
#include    "Stroika/Frameworks/StroikaPreComp.h"

#include    <mutex>
#include    <iostream>

#include    "Stroika/Foundation/Characters/Format.h"
#include    "Stroika/Foundation/Characters/String_Constant.h"
#include    "Stroika/Foundation/Execution/CommandLine.h"
#include    "Stroika/Foundation/Execution/WaitableEvent.h"
#include    "Stroika/Foundation/Memory/Optional.h"
#include    "Stroika/Foundation/IO/Network/HTTP/Headers.h"
#include    "Stroika/Foundation/IO/Network/LinkMonitor.h"
#include    "Stroika/Foundation/IO/Network/Listener.h"
#include    "Stroika/Foundation/Streams/iostream/BinaryInputStreamFromIStreamAdapter.h"
#include    "Stroika/Frameworks/UPnP/SSDP/Common.h"
#include    "Stroika/Frameworks/UPnP/SSDP/Server/BasicServer.h"
#include    "Stroika/Frameworks/WebServer/ConnectionManager.h"

using   namespace std;

using   namespace Stroika::Foundation;
using   namespace Stroika::Foundation::IO;
using   namespace Stroika::Foundation::IO::Network;
using   namespace Stroika::Frameworks;
using   namespace Stroika::Frameworks::UPnP;
using   namespace Stroika::Frameworks::UPnP::SSDP;
using   namespace Stroika::Frameworks::WebServer;

using   Characters::String;
using   Characters::String_Constant;
using   Containers::Sequence;
using   Memory::Optional;
using   Server::BasicServer;

namespace {
    struct WebServerForDeviceDescription_ {

        WebServerForDeviceDescription_ (uint16_t webServerPortNumber, const Device& d, const DeviceDescription& dd)
            : fListener ()
        {
            auto onConnect = [d, dd](Socket s) {
                Execution::Thread runConnectionOnAnotherThread ([s, d, dd]() {
                    // If the URLs are served locally, you may want to update the URL based on
                    // IO::Network::GetPrimaryInternetAddress ()
                    Memory::BLOB deviceDescription  =   Stroika::Frameworks::UPnP::Serialize (d, dd);
                    // now read
                    Connection conn (s);
                    conn.ReadHeaders ();    // bad API. Must rethink...
                    conn.GetResponse ().AddHeader (IO::Network::HTTP::HeaderName::kServer, L"stroika-ssdp-server-demo");
                    conn.GetResponse ().write (deviceDescription.begin (), deviceDescription.end ());
                    conn.GetResponse ().SetContentType (DataExchange::PredefinedInternetMediaType::XML_CT ());
                    conn.GetResponse ().End ();
                });
                runConnectionOnAnotherThread.SetThreadName (L"Connection Thread");  // SHOULD use a fancier name (connection#)
                runConnectionOnAnotherThread.Start ();
                //runConnectionOnAnotherThread.WaitForDone ();    // maybe save these in connection mgr so we can force them all shut down...
            };
            fListener = Optional<Listener> (Listener (SocketAddress (Network::V4::kAddrAny, webServerPortNumber), onConnect));
        }

        Optional<Listener>    fListener;
    };
}

int main (int argc, const char* argv[])
{
    try {
        uint16_t    portForOurWS = 8080;

        Device  d;
        d.fLocation.SetPortNumber (portForOurWS);
        d.fServer = UPnP::SSDP::MakeServerHeaderValue (String_Constant (L"MyStroikaBasedSampleProduct/1.0"));
        d.fDeviceID = UPnP::MungePrimaryMacAddrIntoBaseDeviceID (String_Constant (L"315CAAE0-1335-57BF-A178-24C9EE756627"));

        DeviceDescription   deviceInfo;
        deviceInfo.fPresentationURL = URL (String_Constant (L"http://www.sophists.com/"));
        deviceInfo.fDeviceType = String_Constant (L"urn:sophists.com:device:deviceType:1.0");
        deviceInfo.fManufactureName = String_Constant (L"Sophist Solutions, Inc.");
        deviceInfo.fFriendlyName = String_Constant (L"Sophist Solutions fake device");
        deviceInfo.fManufacturingURL = URL (String_Constant (L"http://www.sophists.com/"));
        deviceInfo.fModelDescription = String_Constant (L"long user-friendly title");
        deviceInfo.fModelName = String_Constant (L"model name");
        deviceInfo.fModelNumber = String_Constant (L"model number");
        deviceInfo.fModelURL = URL (String_Constant (L"http://www.sophists.com/"));
        deviceInfo.fSerialNumber = String_Constant (L"manufacturer's serial number");

        WebServerForDeviceDescription_  deviceWS (portForOurWS, d, deviceInfo);
        BasicServer b (d, BasicServer::FrequencyInfo ());
        Execution::WaitableEvent (Execution::WaitableEvent::eAutoReset).Wait ();    // wait forever - til user hits ctrl-c
    }
    catch (...) {
        cerr << "Exception - terminating..." << endl;
        return EXIT_FAILURE;
    }
    return EXIT_SUCCESS;
}
<|endoftext|>