<commit_before>#include "PangoCairo.h"
#include "Cairo.h"
#include <string.h>
#include <stdlib.h>

Persistent<FunctionTemplate> Cairo::constructor;

void
Cairo::Initialize(Handle<Object> target) {
  HandleScope scope;

  // Constructor
  constructor = Persistent<FunctionTemplate>::New(FunctionTemplate::New(Cairo::New));
  constructor->InstanceTemplate()->SetInternalFieldCount(1);
  constructor->SetClassName(String::NewSymbol("Cairo"));

  // Prototype
  //Local<ObjectTemplate> proto = constructor->PrototypeTemplate();
  NODE_SET_PROTOTYPE_METHOD(constructor, "save", Save);
  NODE_SET_PROTOTYPE_METHOD(constructor, "restore", Restore);
  NODE_SET_PROTOTYPE_METHOD(constructor, "setSourceRGB", SetSourceRGB);
  NODE_SET_PROTOTYPE_METHOD(constructor, "setSourceRGBA", SetSourceRGBA);
  NODE_SET_PROTOTYPE_METHOD(constructor, "moveTo", MoveTo);
  NODE_SET_PROTOTYPE_METHOD(constructor, "selectFontFace", SelectFontFace);
  NODE_SET_PROTOTYPE_METHOD(constructor, "setFontSize", SetFontSize);
  NODE_SET_PROTOTYPE_METHOD(constructor, "showText", ShowText);
  NODE_SET_PROTOTYPE_METHOD(constructor, "showGlyphString", ShowGlyphString);
  NODE_SET_PROTOTYPE_METHOD(constructor, "showAGlyph", ShowAGlyph);
  NODE_SET_PROTOTYPE_METHOD(constructor, "rectangle", Rectangle);
  NODE_SET_PROTOTYPE_METHOD(constructor, "drawPNG", DrawPNG);

  NODE_SET_PROTOTYPE_METHOD(constructor, "showPage", ShowPage);
  NODE_SET_PROTOTYPE_METHOD(constructor, "finish", Finish);

  target->Set(String::NewSymbol("Cairo"), constructor->GetFunction());
}

Handle<Value>
Cairo::New(const Arguments &args) {
  HandleScope scope;
  int width = 0, height = 0;
  char* filename = NULL;
  canvas_type_t type = CANVAS_TYPE_IMAGE;
  if (args[0]->IsNumber()) width = args[0]->Uint32Value();
  if (args[1]->IsNumber()) height = args[1]->Uint32Value();
  if (args[2]->IsString()) type = !strcmp("pdf", *String::AsciiValue(args[2]))
    ? CANVAS_TYPE_PDF
    : CANVAS_TYPE_IMAGE;
  if (args[3]->IsString()) filename = *String::AsciiValue(args[3]);
  Cairo *context = new Cairo(width, height, type, filename);
  context->Wrap(args.This());
  return args.This();
}

Cairo::Cairo(int w, int h, canvas_type_t t, char* filename): ObjectWrap() {
  width = w;
  _surface = NULL;

  if (CANVAS_TYPE_PDF == t) {
    _surface = cairo_pdf_surface_create(filename, w, h);
    if (cairo_surface_status(_surface) != CAIRO_STATUS_SUCCESS) {
      ThrowException(String::New(cairo_status_to_string(cairo_surface_status(_surface))));
    }
  } else {
    _surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, w, h);
    assert(_surface);
    V8::AdjustAmountOfExternalAllocatedMemory(4 * w * h);
  }
  _cairo = cairo_create(_surface);
}

Handle<Value>
Cairo::Save(const Arguments &args) {
  HandleScope scope;
  Cairo *cc = ObjectWrap::Unwrap<Cairo>(args.This());
  cairo_save(cc->_cairo);
  return Undefined();
}

Handle<Value>
Cairo::Restore(const Arguments &args) {
  HandleScope scope;
  Cairo *cc = ObjectWrap::Unwrap<Cairo>(args.This());
  cairo_restore(cc->_cairo);
  return Undefined();
}

Handle<Value>
Cairo::SetSourceRGB(const Arguments &args) {
  HandleScope scope;
  Cairo *cc = ObjectWrap::Unwrap<Cairo>(args.This());
  cairo_set_source_rgb(cc->_cairo, args[0]->NumberValue(),
      args[1]->NumberValue(),args[2]->NumberValue());
  return Undefined();
}

Handle<Value>
Cairo::SetSourceRGBA(const Arguments &args) {
  HandleScope scope;
  Cairo *cc = ObjectWrap::Unwrap<Cairo>(args.This());
  cairo_set_source_rgba(cc->_cairo, args[0]->NumberValue(),
      args[1]->NumberValue(),args[2]->NumberValue(), args[3]->NumberValue());
  return Undefined();
}

Handle<Value>
Cairo::MoveTo(const Arguments &args) {
  HandleScope scope;
  Cairo *cc = ObjectWrap::Unwrap<Cairo>(args.This());
  cairo_move_to(cc->_cairo, args[0]->NumberValue(), args[1]->NumberValue());
  return Undefined();
}

Handle<Value>
Cairo::Rectangle(const Arguments &args) {
  HandleScope scope;
  Cairo *cc = ObjectWrap::Unwrap<Cairo>(args.This());

  cairo_set_line_width(cc->_cairo, 0.5);
  cairo_rectangle(cc->_cairo, args[0]->NumberValue(), args[1]->NumberValue(),args[2]->NumberValue(), args[3]->NumberValue());
  cairo_stroke(cc->_cairo);
  return Undefined();
}

Handle<Value>
Cairo::DrawPNG(const Arguments &args) {
  HandleScope scope;
  Cairo *cc = ObjectWrap::Unwrap<Cairo>(args.This());
  cairo_surface_t *image = cairo_image_surface_create_from_png(*String::AsciiValue(args[0]));
  double desired_width = args[3]->NumberValue();
  double desired_height = args[4]->NumberValue();
  cairo_matrix_t matrix;
  cairo_pattern_t *p;
  cairo_save(cc->_cairo);
  cairo_set_source_surface(cc->_cairo, image, args[1]->NumberValue(), args[2]->NumberValue());
  p = cairo_get_source(cc->_cairo);
  if (desired_width || desired_height) {
    double image_width = cairo_image_surface_get_width(image);
    double image_height = cairo_image_surface_get_height(image);
    double sx = 0.0;
    double sy = 0.0;
    if (desired_width) sx = image_width / desired_width;
    if (desired_height) sy = image_height / desired_height;
    cairo_matrix_init_scale(&matrix, sx ? sx : sy, sy ? sy : sx);
  } else {
    cairo_matrix_init_identity(&matrix);
  }
  //printf("%f, %f\n", );
  cairo_matrix_translate(&matrix, -args[1]->NumberValue(), -args[2]->NumberValue());
  cairo_pattern_set_matrix(p, &matrix);
  cairo_paint(cc->_cairo);
  cairo_restore(cc->_cairo);
  return Undefined();
}

Handle<Value>
Cairo::SelectFontFace(const Arguments &args) {
  HandleScope scope;
  String::Utf8Value f (args[0]->ToString());
  Cairo *cc = ObjectWrap::Unwrap<Cairo>(args.This());
  cairo_select_font_face(cc->_cairo, *f, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); // XXX
//      args[1]->IntegerValue(),args[2]->IntegerValue());
  return Undefined();
}

Handle<Value>
Cairo::SetFontSize(const Arguments &args) {
  HandleScope scope;
  Cairo *cc = ObjectWrap::Unwrap<Cairo>(args.This());
  cairo_set_font_size(cc->_cairo, args[0]->NumberValue());
  return Undefined();
}

Handle<Value>
Cairo::ShowText(const Arguments &args) {
  HandleScope scope;
  String::Utf8Value t (args[0]->ToString());
  Cairo *cc = ObjectWrap::Unwrap<Cairo>(args.This());
  cairo_show_text(cc->_cairo, *t);
  return Undefined();
}

Handle<Value>
Cairo::ShowGlyphString(const Arguments &args) {
  HandleScope scope;
  Cairo *cc = ObjectWrap::Unwrap<Cairo>(args.This());

  PangoFont *pf = (PangoFont*)External::Unwrap(args[0]);
  PangoGlyphString *g = (PangoGlyphString*)External::Unwrap(args[1]);

  pango_cairo_show_glyph_string(cc->_cairo, pf, g);
  return Undefined();
}

Handle<Value>
Cairo::ShowAGlyph(const Arguments &args) {
  HandleScope scope;
  Cairo *cc = ObjectWrap::Unwrap<Cairo>(args.This());
  gint *lg = { 0 };
  PangoFont *pf = (PangoFont*)External::Unwrap(args[0]);
  PangoGlyphInfo *g = (PangoGlyphInfo*)External::Unwrap(args[1]);
  PangoGlyphString gs = {1,g,lg};

  pango_cairo_show_glyph_string(cc->_cairo, pf, &gs);
  return v8::Boolean::New(true);
}

Handle<Value>
Cairo::ShowPage(const Arguments &args) {
  HandleScope scope;
  Cairo *cc = ObjectWrap::Unwrap<Cairo>(args.This());
  cairo_show_page(cc->_cairo);
  return v8::Boolean::New(true);
}

Handle<Value>
Cairo::Finish(const Arguments &args) {
  HandleScope scope;
  Cairo *cc = ObjectWrap::Unwrap<Cairo>(args.This());

  if (cc->_surface) {
    cairo_surface_destroy(cc->_surface);
    cc->_surface = NULL;
  }
  if (cc->_cairo) {
    cairo_destroy(cc->_cairo);
    cc->_cairo = NULL;
  }
  return v8::Boolean::New(true);
}

Cairo::~Cairo() {
  if (_surface) {
    cairo_surface_destroy(_surface);
    _surface = NULL;
  }
  if (_cairo) {
    cairo_destroy(_cairo);
    _cairo = NULL;
  }
}
<commit_msg>I don't know why this fails on Linux, but assigning to a char* turns up empty.<commit_after>#include "PangoCairo.h"
#include "Cairo.h"
#include <string.h>
#include <stdlib.h>

Persistent<FunctionTemplate> Cairo::constructor;

void
Cairo::Initialize(Handle<Object> target) {
  HandleScope scope;

  // Constructor
  constructor = Persistent<FunctionTemplate>::New(FunctionTemplate::New(Cairo::New));
  constructor->InstanceTemplate()->SetInternalFieldCount(1);
  constructor->SetClassName(String::NewSymbol("Cairo"));

  // Prototype
  //Local<ObjectTemplate> proto = constructor->PrototypeTemplate();
  NODE_SET_PROTOTYPE_METHOD(constructor, "save", Save);
  NODE_SET_PROTOTYPE_METHOD(constructor, "restore", Restore);
  NODE_SET_PROTOTYPE_METHOD(constructor, "setSourceRGB", SetSourceRGB);
  NODE_SET_PROTOTYPE_METHOD(constructor, "setSourceRGBA", SetSourceRGBA);
  NODE_SET_PROTOTYPE_METHOD(constructor, "moveTo", MoveTo);
  NODE_SET_PROTOTYPE_METHOD(constructor, "selectFontFace", SelectFontFace);
  NODE_SET_PROTOTYPE_METHOD(constructor, "setFontSize", SetFontSize);
  NODE_SET_PROTOTYPE_METHOD(constructor, "showText", ShowText);
  NODE_SET_PROTOTYPE_METHOD(constructor, "showGlyphString", ShowGlyphString);
  NODE_SET_PROTOTYPE_METHOD(constructor, "showAGlyph", ShowAGlyph);
  NODE_SET_PROTOTYPE_METHOD(constructor, "rectangle", Rectangle);
  NODE_SET_PROTOTYPE_METHOD(constructor, "drawPNG", DrawPNG);

  NODE_SET_PROTOTYPE_METHOD(constructor, "showPage", ShowPage);
  NODE_SET_PROTOTYPE_METHOD(constructor, "finish", Finish);

  target->Set(String::NewSymbol("Cairo"), constructor->GetFunction());
}

Handle<Value>
Cairo::New(const Arguments &args) {
  HandleScope scope;
  int width = 0, height = 0;
  canvas_type_t type = CANVAS_TYPE_IMAGE;
  if (args[0]->IsNumber()) width = args[0]->Uint32Value();
  if (args[1]->IsNumber()) height = args[1]->Uint32Value();
  if (args[2]->IsString()) type = !strcmp("pdf", *String::AsciiValue(args[2]))
    ? CANVAS_TYPE_PDF
    : CANVAS_TYPE_IMAGE;
  Cairo *context = new Cairo(width, height, type, *String::AsciiValue(args[3]));
  context->Wrap(args.This());
  return args.This();
}

Cairo::Cairo(int w, int h, canvas_type_t t, char* filename): ObjectWrap() {
  width = w;
  _surface = NULL;

  if (CANVAS_TYPE_PDF == t) {
printf("filename: %s, width: %i, height: %i\n", filename, w, h);
    _surface = cairo_pdf_surface_create(filename, w, h);
    if (cairo_surface_status(_surface) != CAIRO_STATUS_SUCCESS) {
      ThrowException(String::New(cairo_status_to_string(cairo_surface_status(_surface))));
    }
  } else {
    _surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, w, h);
    assert(_surface);
    V8::AdjustAmountOfExternalAllocatedMemory(4 * w * h);
  }
  _cairo = cairo_create(_surface);
}

Handle<Value>
Cairo::Save(const Arguments &args) {
  HandleScope scope;
  Cairo *cc = ObjectWrap::Unwrap<Cairo>(args.This());
  cairo_save(cc->_cairo);
  return Undefined();
}

Handle<Value>
Cairo::Restore(const Arguments &args) {
  HandleScope scope;
  Cairo *cc = ObjectWrap::Unwrap<Cairo>(args.This());
  cairo_restore(cc->_cairo);
  return Undefined();
}

Handle<Value>
Cairo::SetSourceRGB(const Arguments &args) {
  HandleScope scope;
  Cairo *cc = ObjectWrap::Unwrap<Cairo>(args.This());
  cairo_set_source_rgb(cc->_cairo, args[0]->NumberValue(),
      args[1]->NumberValue(),args[2]->NumberValue());
  return Undefined();
}

Handle<Value>
Cairo::SetSourceRGBA(const Arguments &args) {
  HandleScope scope;
  Cairo *cc = ObjectWrap::Unwrap<Cairo>(args.This());
  cairo_set_source_rgba(cc->_cairo, args[0]->NumberValue(),
      args[1]->NumberValue(),args[2]->NumberValue(), args[3]->NumberValue());
  return Undefined();
}

Handle<Value>
Cairo::MoveTo(const Arguments &args) {
  HandleScope scope;
  Cairo *cc = ObjectWrap::Unwrap<Cairo>(args.This());
  cairo_move_to(cc->_cairo, args[0]->NumberValue(), args[1]->NumberValue());
  return Undefined();
}

Handle<Value>
Cairo::Rectangle(const Arguments &args) {
  HandleScope scope;
  Cairo *cc = ObjectWrap::Unwrap<Cairo>(args.This());

  cairo_set_line_width(cc->_cairo, 0.5);
  cairo_rectangle(cc->_cairo, args[0]->NumberValue(), args[1]->NumberValue(),args[2]->NumberValue(), args[3]->NumberValue());
  cairo_stroke(cc->_cairo);
  return Undefined();
}

Handle<Value>
Cairo::DrawPNG(const Arguments &args) {
  HandleScope scope;
  Cairo *cc = ObjectWrap::Unwrap<Cairo>(args.This());
  cairo_surface_t *image = cairo_image_surface_create_from_png(*String::AsciiValue(args[0]));
  double desired_width = args[3]->NumberValue();
  double desired_height = args[4]->NumberValue();
  cairo_matrix_t matrix;
  cairo_pattern_t *p;
  cairo_save(cc->_cairo);
  cairo_set_source_surface(cc->_cairo, image, args[1]->NumberValue(), args[2]->NumberValue());
  p = cairo_get_source(cc->_cairo);
  if (desired_width || desired_height) {
    double image_width = cairo_image_surface_get_width(image);
    double image_height = cairo_image_surface_get_height(image);
    double sx = 0.0;
    double sy = 0.0;
    if (desired_width) sx = image_width / desired_width;
    if (desired_height) sy = image_height / desired_height;
    cairo_matrix_init_scale(&matrix, sx ? sx : sy, sy ? sy : sx);
  } else {
    cairo_matrix_init_identity(&matrix);
  }
  //printf("%f, %f\n", );
  cairo_matrix_translate(&matrix, -args[1]->NumberValue(), -args[2]->NumberValue());
  cairo_pattern_set_matrix(p, &matrix);
  cairo_paint(cc->_cairo);
  cairo_restore(cc->_cairo);
  return Undefined();
}

Handle<Value>
Cairo::SelectFontFace(const Arguments &args) {
  HandleScope scope;
  String::Utf8Value f (args[0]->ToString());
  Cairo *cc = ObjectWrap::Unwrap<Cairo>(args.This());
  cairo_select_font_face(cc->_cairo, *f, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); // XXX
//      args[1]->IntegerValue(),args[2]->IntegerValue());
  return Undefined();
}

Handle<Value>
Cairo::SetFontSize(const Arguments &args) {
  HandleScope scope;
  Cairo *cc = ObjectWrap::Unwrap<Cairo>(args.This());
  cairo_set_font_size(cc->_cairo, args[0]->NumberValue());
  return Undefined();
}

Handle<Value>
Cairo::ShowText(const Arguments &args) {
  HandleScope scope;
  String::Utf8Value t (args[0]->ToString());
  Cairo *cc = ObjectWrap::Unwrap<Cairo>(args.This());
  cairo_show_text(cc->_cairo, *t);
  return Undefined();
}

Handle<Value>
Cairo::ShowGlyphString(const Arguments &args) {
  HandleScope scope;
  Cairo *cc = ObjectWrap::Unwrap<Cairo>(args.This());

  PangoFont *pf = (PangoFont*)External::Unwrap(args[0]);
  PangoGlyphString *g = (PangoGlyphString*)External::Unwrap(args[1]);

  pango_cairo_show_glyph_string(cc->_cairo, pf, g);
  return Undefined();
}

Handle<Value>
Cairo::ShowAGlyph(const Arguments &args) {
  HandleScope scope;
  Cairo *cc = ObjectWrap::Unwrap<Cairo>(args.This());
  gint *lg = { 0 };
  PangoFont *pf = (PangoFont*)External::Unwrap(args[0]);
  PangoGlyphInfo *g = (PangoGlyphInfo*)External::Unwrap(args[1]);
  PangoGlyphString gs = {1,g,lg};

  pango_cairo_show_glyph_string(cc->_cairo, pf, &gs);
  return v8::Boolean::New(true);
}

Handle<Value>
Cairo::ShowPage(const Arguments &args) {
  HandleScope scope;
  Cairo *cc = ObjectWrap::Unwrap<Cairo>(args.This());
  cairo_show_page(cc->_cairo);
  return v8::Boolean::New(true);
}

Handle<Value>
Cairo::Finish(const Arguments &args) {
  HandleScope scope;
  Cairo *cc = ObjectWrap::Unwrap<Cairo>(args.This());

  if (cc->_surface) {
    cairo_surface_destroy(cc->_surface);
    cc->_surface = NULL;
  }
  if (cc->_cairo) {
    cairo_destroy(cc->_cairo);
    cc->_cairo = NULL;
  }
  return v8::Boolean::New(true);
}

Cairo::~Cairo() {
  if (_surface) {
    cairo_surface_destroy(_surface);
    _surface = NULL;
  }
  if (_cairo) {
    cairo_destroy(_cairo);
    _cairo = NULL;
  }
}
<|endoftext|>


<commit_before>/*
  pvsops.c: pvs and other spectral-based opcodes

  Copyright (C) 2017 Victor Lazzarini
  This file is part of Csound.

  The Csound Library 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.

  Csound 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 Csound; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  02110-1301 USA
*/
#include <algorithm>
#include <plugin.h>

struct PVTrace : csnd::FPlugin<1, 2> {
  csnd::AuxMem<float> amps;
  static constexpr char const *otypes = "f";
  static constexpr char const *itypes = "fk";

  int init() {
    if (inargs.fsig_data(0).isSliding())
      return csound->init_error("sliding not supported");

    if (inargs.fsig_data(0).fsig_format() != csnd::fsig_format::pvs &&
        inargs.fsig_data(0).fsig_format() != csnd::fsig_format::polar)
      return csound->init_error("fsig format not supported");

    amps.allocate(csound, inargs.fsig_data(0).nbins());
    csnd::Fsig &fout = outargs.fsig_data(0);
    fout.init(csound, inargs.fsig_data(0));
    framecount = 0;
    return OK;
  }

  int kperf() {
    csnd::pv_frame &fin = inargs.fsig_data(0);
    csnd::pv_frame &fout = outargs.fsig_data(0);

    if (framecount < fin.count()) {
      int n = fin.len() - (int)inargs[1];
      float thrsh;
      std::transform(fin.begin(), fin.end(), amps.begin(),
                     [](csnd::pv_bin f) { return f.amp(); });
      std::nth_element(amps.begin(), amps.begin() + n, amps.end());
      thrsh = amps[n];
      std::transform(fin.begin(), fin.end(), fout.begin(),
                     [thrsh](csnd::pv_bin f) {
                       return f.amp() >= thrsh ? f : csnd::pv_bin();
                     });
      framecount = fout.count(fin.count());
    }
    return OK;
  }
};

struct TVConv : csnd::Plugin<1, 6> {
  csnd::AuxMem<MYFLT> ir;
  csnd::AuxMem<MYFLT> in;
  csnd::AuxMem<MYFLT> insp;
  csnd::AuxMem<MYFLT> irsp;
  csnd::AuxMem<MYFLT> out;
  csnd::AuxMem<MYFLT> saved;
  csnd::AuxMem<MYFLT>::iterator itn;
  csnd::AuxMem<MYFLT>::iterator itr;
  csnd::AuxMem<MYFLT>::iterator itnsp;
  csnd::AuxMem<MYFLT>::iterator itrsp;
  uint32_t n;
  uint32_t fils;
  uint32_t pars;
  uint32_t ffts;
  csnd::fftp fwd, inv;
  typedef std::complex<MYFLT> cmplx;

  uint32_t rpow2(uint32_t n) {
    uint32_t v = 2;
    while (v <= n)
      v <<= 1;
    if ((n - (v >> 1)) < (v - n))
      return v >> 1;
    else
      return v;
  }

  cmplx *to_cmplx(MYFLT *f) { return reinterpret_cast<cmplx *>(f); }

  cmplx real_prod(cmplx &a, cmplx &b) {
    return cmplx(a.real() * b.real(), a.imag() * b.imag());
  }

  int init() {
    pars = inargs[4];
    fils = inargs[5];
    if (pars > fils)
      std::swap(pars, fils);
    if (pars > 1) {
      pars = rpow2(pars);
      fils = rpow2(fils) * 2;
      ffts = pars * 2;
      fwd = csound->fft_setup(ffts, FFT_FWD);
      inv = csound->fft_setup(ffts, FFT_INV);
      out.allocate(csound, ffts);
      insp.allocate(csound, fils);
      irsp.allocate(csound, fils);
      saved.allocate(csound, pars);
      ir.allocate(csound, fils);
      in.allocate(csound, fils);
      itnsp = insp.begin();
      itrsp = insp.begin();
      n = 0;
    } else {
      ir.allocate(csound, fils);
      in.allocate(csound, fils);
    }
    itn = in.begin();
    itr = ir.begin();
    return OK;
  }

  int pconv() {
    csnd::AudioSig insig(this, inargs(0));
    csnd::AudioSig irsig(this, inargs(1));
    csnd::AudioSig outsig(this, outargs(0));
    auto irp = irsig.begin();
    auto inp = insig.begin();
    auto *frz1 = inargs(2);
    auto *frz2 = inargs(3);
    auto inc1 = csound->is_asig(frz1);
    auto inc2 = csound->is_asig(frz2);

    for (auto &s : outsig) {
      if (*frz1 > 0)
        itn[n] = *inp;
      if (*frz2 > 0)
        itr[n] = *irp;

      s = out[n] + saved[n];
      saved[n] = out[n + pars];
      if (++n == pars) {
        cmplx *ins, *irs, *ous = to_cmplx(out.data());
        std::copy(itn, itn + ffts, itnsp);
        std::copy(itr, itr + ffts, itrsp);
        std::fill(out.begin(), out.end(), 0.);
        // FFT
        csound->rfft(fwd, itnsp);
        csound->rfft(fwd, itrsp);
        // increment iterators
        itnsp += ffts, itrsp += ffts;
        itn += ffts, itr += ffts;
        if (itnsp == insp.end()) {
          itnsp = insp.begin();
          itrsp = irsp.begin();
          itn = in.begin();
          itr = ir.begin();
        }
        // spectral delay line
        for (csnd::AuxMem<MYFLT>::iterator it1 = itnsp, it2 = irsp.end() - ffts;
             it2 >= irsp.begin(); it1 += ffts, it2 -= ffts) {
          if (it1 == insp.end())
            it1 = insp.begin();
          ins = to_cmplx(it1);
          irs = to_cmplx(it2);
          // spectral product
          for (uint32_t i = 1; i < pars; i++)
            ous[i] += ins[i] * irs[i];
          ous[0] += real_prod(ins[0], irs[0]);
        }
        // IFFT
        csound->rfft(inv, out.data());
        n = 0;
      }
      frz1 += inc1, frz2 += inc2;
      irp++, inp++;
    }
    return OK;
  }

  int dconv() {
    csnd::AudioSig insig(this, inargs(0));
    csnd::AudioSig irsig(this, inargs(1));
    csnd::AudioSig outsig(this, outargs(0));
    auto irp = irsig.begin();
    auto inp = insig.begin();
    auto frz1 = inargs(2);
    auto frz2 = inargs(3);
    auto inc1 = csound->is_asig(frz1);
    auto inc2 = csound->is_asig(frz2);

    for (auto &s : outsig) {
      if (*frz1 > 0)
        *itn = *inp;
      if (*frz2 > 0)
        *itr = *irp;
      itn++, itr++;
      if (itn == in.end()) {
        itn = in.begin();
        itr = ir.begin();
      }
      s = 0.;
      for (csnd::AuxMem<MYFLT>::iterator it1 = itn, it2 = ir.end() - 1;
           it2 >= ir.begin(); it1++, it2--) {
        if (it1 == in.end())
          it1 = in.begin();
        s += *it1 * *it2;
      }
      frz1 += inc1, frz2 += inc2;
      inp++, irp++;
    }
    return OK;
  }

  int aperf() {
    if (pars > 1)
      return pconv();
    else
      return dconv();
  }
};

/*
class PrintThread : public csnd::Thread {
  std::atomic_bool splock;
  std::atomic_bool on;
  std::string message;

  void lock() {
    bool tmp = false;
    while(!splock.compare_exchange_weak(tmp,true))
      tmp = false;
  }

  void unlock() {
    splock = false;
  }

  uintptr_t run() {
    std::string old;
    while(on) {
      lock();
      if(old.compare(message)) {
       csound->message(message.c_str());
       old = message;
      }
      unlock();
    }
    return 0;
  }

public:
  PrintThread(csnd::Csound *csound)
    : Thread(csound), splock(false), on(true), message("") {};

  ~PrintThread(){
    on = false;
    join();
  }

  void set_message(const char *m) {
    lock();
    message = m;
    unlock();
  }

};

struct TPrint : csnd::Plugin<0, 1> {
  static constexpr char const *otypes = "";
  static constexpr char const *itypes = "S";
  PrintThread t;

  int init() {
    csound->plugin_deinit(this);
    csnd::constr(&t, csound);
    return OK;
  }

  int deinit() {
    csnd::destr(&t);
    return OK;
  }

  int kperf() {
    t.set_message(inargs.str_data(0).data);
    return OK;
  }
};
*/

#include <modload.h>
void csnd::on_load(Csound *csound) {
  csnd::plugin<PVTrace>(csound, "pvstrace", csnd::thread::ik);
  csnd::plugin<TVConv>(csound, "tvconv", "a", "aaxxii", csnd::thread::ik);
}
<commit_msg>fixed TVconv<commit_after>/*
  pvsops.c: pvs and other spectral-based opcodes

  Copyright (C) 2017 Victor Lazzarini
  This file is part of Csound.

  The Csound Library 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.

  Csound 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 Csound; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  02110-1301 USA
*/
#include <algorithm>
#include <plugin.h>

struct PVTrace : csnd::FPlugin<1, 2> {
  csnd::AuxMem<float> amps;
  static constexpr char const *otypes = "f";
  static constexpr char const *itypes = "fk";

  int init() {
    if (inargs.fsig_data(0).isSliding())
      return csound->init_error("sliding not supported");

    if (inargs.fsig_data(0).fsig_format() != csnd::fsig_format::pvs &&
        inargs.fsig_data(0).fsig_format() != csnd::fsig_format::polar)
      return csound->init_error("fsig format not supported");

    amps.allocate(csound, inargs.fsig_data(0).nbins());
    csnd::Fsig &fout = outargs.fsig_data(0);
    fout.init(csound, inargs.fsig_data(0));
    framecount = 0;
    return OK;
  }

  int kperf() {
    csnd::pv_frame &fin = inargs.fsig_data(0);
    csnd::pv_frame &fout = outargs.fsig_data(0);

    if (framecount < fin.count()) {
      int n = fin.len() - (int)inargs[1];
      float thrsh;
      std::transform(fin.begin(), fin.end(), amps.begin(),
                     [](csnd::pv_bin f) { return f.amp(); });
      std::nth_element(amps.begin(), amps.begin() + n, amps.end());
      thrsh = amps[n];
      std::transform(fin.begin(), fin.end(), fout.begin(),
                     [thrsh](csnd::pv_bin f) {
                       return f.amp() >= thrsh ? f : csnd::pv_bin();
                     });
      framecount = fout.count(fin.count());
    }
    return OK;
  }
};

struct TVConv : csnd::Plugin<1, 6> {
  csnd::AuxMem<MYFLT> ir;
  csnd::AuxMem<MYFLT> in;
  csnd::AuxMem<MYFLT> insp;
  csnd::AuxMem<MYFLT> irsp;
  csnd::AuxMem<MYFLT> out;
  csnd::AuxMem<MYFLT> saved;
  csnd::AuxMem<MYFLT>::iterator itn;
  csnd::AuxMem<MYFLT>::iterator itr;
  csnd::AuxMem<MYFLT>::iterator itnsp;
  csnd::AuxMem<MYFLT>::iterator itrsp;
  uint32_t n;
  uint32_t fils;
  uint32_t pars;
  uint32_t ffts;
  csnd::fftp fwd, inv;
  typedef std::complex<MYFLT> cmplx;

  uint32_t rpow2(uint32_t n) {
    uint32_t v = 2;
    while (v <= n)
      v <<= 1;
    if ((n - (v >> 1)) < (v - n))
      return v >> 1;
    else
      return v;
  }

  cmplx *to_cmplx(MYFLT *f) { return reinterpret_cast<cmplx *>(f); }

  cmplx real_prod(cmplx &a, cmplx &b) {
    return cmplx(a.real() * b.real(), a.imag() * b.imag());
  }

  int init() {
    pars = inargs[4];
    fils = inargs[5];
    if (pars > fils)
      std::swap(pars, fils);
    if (pars > 1) {
      pars = rpow2(pars);
      fils = rpow2(fils) * 2;
      ffts = pars * 2;
      fwd = csound->fft_setup(ffts, FFT_FWD);
      inv = csound->fft_setup(ffts, FFT_INV);
      out.allocate(csound, ffts);
      insp.allocate(csound, fils);
      irsp.allocate(csound, fils);
      saved.allocate(csound, pars);
      ir.allocate(csound, fils);
      in.allocate(csound, fils);
      itnsp = insp.begin();
      itrsp = insp.begin();
      n = 0;
    } else {
      ir.allocate(csound, fils);
      in.allocate(csound, fils);
    }
    itn = in.begin();
    itr = ir.begin();
    return OK;
  }

  int pconv() {
    csnd::AudioSig insig(this, inargs(0));
    csnd::AudioSig irsig(this, inargs(1));
    csnd::AudioSig outsig(this, outargs(0));
    auto irp = irsig.begin();
    auto inp = insig.begin();
    auto *frz1 = inargs(2);
    auto *frz2 = inargs(3);
    auto inc1 = csound->is_asig(frz1);
    auto inc2 = csound->is_asig(frz2);

    for (auto &s : outsig) {
      if (*frz1 > 0)
        itn[n] = *inp;
      if (*frz2 > 0)
        itr[n] = *irp;

      s = out[n] + saved[n];
      saved[n] = out[n + pars];
      if (++n == pars) {
        cmplx *ins, *irs, *ous = to_cmplx(out.data());
        std::copy(itn, itn + ffts, itnsp);
        std::copy(itr, itr + ffts, itrsp);
        std::fill(out.begin(), out.end(), 0.);
        // FFT
        csound->rfft(fwd, itnsp);
        csound->rfft(fwd, itrsp);
        // increment iterators
        itnsp += ffts, itrsp += ffts;
        itn += ffts, itr += ffts;
        if (itnsp == insp.end()) {
          itnsp = insp.begin();
          itrsp = irsp.begin();
          itn = in.begin();
          itr = ir.begin();
        }
        // spectral delay line
        for (csnd::AuxMem<MYFLT>::iterator it1 = itnsp, it2 = irsp.end() - ffts;
             it2 >= irsp.begin(); it1 += ffts, it2 -= ffts) {
          if (it1 == insp.end())
            it1 = insp.begin();
          ins = to_cmplx(it1);
          irs = to_cmplx(it2);
          // spectral product
          for (uint32_t i = 1; i < pars; i++)
            ous[i] += ins[i] * irs[i];
          ous[0] += real_prod(ins[0], irs[0]);
        }
        // IFFT
        csound->rfft(inv, out.data());
        n = 0;
      }
      frz1 += inc1, frz2 += inc2;
      irp++, inp++;
    }
    return OK;
  }

  int dconv() {
    csnd::AudioSig insig(this, inargs(0));
    csnd::AudioSig irsig(this, inargs(1));
    csnd::AudioSig outsig(this, outargs(0));
    auto irp = irsig.begin();
    auto inp = insig.begin();
    auto frz1 = inargs(2);
    auto frz2 = inargs(3);
    auto inc1 = csound->is_asig(frz1);
    auto inc2 = csound->is_asig(frz2);

    for (auto &s : outsig) {
      if (*frz1 > 0)
        *itn = *inp;
      if (*frz2 > 0)
        *itr = *irp;
      itn++, itr++;
      if (itn == in.end()) {
        itn = in.begin();
        itr = ir.begin();
      }
      s = 0.;
      for (csnd::AuxMem<MYFLT>::iterator it1 = itn, it2 = ir.end() - 1;
           it2 >= ir.begin(); it1++, it2--) {
        if (it1 == in.end())
          it1 = in.begin();
        s += *it1 * *it2;
      }
      frz1 += inc1, frz2 += inc2;
      inp++, irp++;
    }
    return OK;
  }

  int aperf() {
    if (pars > 1)
      return pconv();
    else
      return dconv();
  }
};

/*
class PrintThread : public csnd::Thread {
  std::atomic_bool splock;
  std::atomic_bool on;
  std::string message;

  void lock() {
    bool tmp = false;
    while(!splock.compare_exchange_weak(tmp,true))
      tmp = false;
  }

  void unlock() {
    splock = false;
  }

  uintptr_t run() {
    std::string old;
    while(on) {
      lock();
      if(old.compare(message)) {
       csound->message(message.c_str());
       old = message;
      }
      unlock();
    }
    return 0;
  }

public:
  PrintThread(csnd::Csound *csound)
    : Thread(csound), splock(false), on(true), message("") {};

  ~PrintThread(){
    on = false;
    join();
  }

  void set_message(const char *m) {
    lock();
    message = m;
    unlock();
  }

};

struct TPrint : csnd::Plugin<0, 1> {
  static constexpr char const *otypes = "";
  static constexpr char const *itypes = "S";
  PrintThread t;

  int init() {
    csound->plugin_deinit(this);
    csnd::constr(&t, csound);
    return OK;
  }

  int deinit() {
    csnd::destr(&t);
    return OK;
  }

  int kperf() {
    t.set_message(inargs.str_data(0).data);
    return OK;
  }
};
*/

#include <modload.h>
void csnd::on_load(Csound *csound) {
  csnd::plugin<PVTrace>(csound, "pvstrace", csnd::thread::ik);
  csnd::plugin<TVConv>(csound, "tvconv", "a", "aaxxii", csnd::thread::ia);
}
<|endoftext|>


<commit_before>#include <qnumeric.h>
#include <qwt_plot.h>
#include <qwt_plot_grid.h>
#include <qwt_plot_canvas.h>
#include <qwt_plot_spectrogram.h>
#include <qwt_plot_layout.h>
#include <qwt_plot_rescaler.h>
#include <qwt_color_map.h>
#include <qwt_scale_engine.h>
#include <qwt_scale_widget.h>
#include <qwt_matrix_raster_data.h>
#include <algorithm>
#include <QDebug>
#include <QColor>

#include "spectroscatterplot.h"
#include "colormaps.h"
#include "mddasplotconfig.h"
#include "mddasdatapoint.h"
#include "zoomer.h"

class SpectrogramData: public QwtMatrixRasterData {
public:
    SpectrogramData(uint x_max, uint y_max) {
        _max_v = 0;
        x_lim = x_max;
        y_lim = y_max;

        /* Create the private array */
        /* Note: this is mapped via index magic */
        this->vals = new uint[x_max*y_max];
        /* Init the private array to 0 */
        memset(vals, 0, x_max*y_max*sizeof(unsigned int));

        /* Set the axes intervals */
        setInterval( Qt::XAxis, QwtInterval( 0.0, x_max ) );
        setInterval( Qt::YAxis, QwtInterval( 0.0, y_max ) );
        setInterval( Qt::ZAxis, QwtInterval( 0.0, 1.0 ) );
    }

    ~SpectrogramData() {
        /* IMPORTANT! Delete the vals array */
        delete[] this->vals;
        //this->vals = 0;
    }

    inline void updateScale() {
        /* Update the scale to reflect the largest Z value */
        //setInterval( Qt::ZAxis, QwtInterval( 0.0, (double)*std::max_element(vals, vals + x_lim*y_lim)));
        setInterval( Qt::ZAxis, QwtInterval( 0.1, (double)_max_v));
    }

    inline void append(const QVector<MDDASDataPoint> &vec) {

        /* Append new z vals. */
        for (uint i = 0; i < (uint)vec.size(); i++) {
            if (((uint)vec[i].x() < x_lim) && ((uint)vec[i].y() < y_lim)) {
                vals[y_lim*(uint)vec[i].x() + (uint)vec[i].y()] += 1;
                /* This handles max amplitude without having to loop
                   over the entire matrix */
                if (vals[y_lim*(uint)vec[i].x() + (uint)vec[i].y()] > _max_v) {
                    _max_v += 1;
                }

            }
        }
    }

    inline QRectF pixelHint(const QRectF &area) const {
        Q_UNUSED( area )

        QRectF rect;

        const QwtInterval intervalX = interval( Qt::XAxis );
        const QwtInterval intervalY = interval( Qt::YAxis );
        if ( intervalX.isValid() && intervalY.isValid() ) {
            rect = QRectF( intervalX.minValue(), intervalY.minValue(),
                           1.0, 1.0 );
        }

        return rect;
    }

    inline void clear() {
        /* Set all values to 0. */
        memset(vals, 0, x_lim*y_lim*sizeof(unsigned int));
        /* Set max amplitude to 0 */
        _max_v = 0;
    }

    virtual double value(double x, double y) const {
        const QwtInterval xInterval = interval( Qt::XAxis );
        const QwtInterval yInterval = interval( Qt::YAxis );

        /* Use only data within the plot region */
        if ( !( xInterval.contains(x) && yInterval.contains(y) ) )
            return qQNaN();

        /* Overloaded value function that returns image z vals from map. */
        return (double)vals[y_lim*(uint)x + (uint)y];
        // if (x < x_lim && y < y_lim) {
        //     return (double)vals[y_lim*(uint)x + (uint)y];
        // } else {
        //     /* Edge case! */
        //     return (double)0;
        // }
    }

private:
    uint *vals; /* matrix of image z values */
    uint x_lim;
    uint y_lim;
    uint _max_v;
};

SpectroScatterPlot::SpectroScatterPlot(QWidget *parent, uint x_max, uint y_max):
    QwtPlot(parent),
    d_curve(NULL)
{
    setFrameStyle(QFrame::NoFrame);
    setLineWidth(0);
    //setCanvasLineWidth(0);

    /* Color map mode linear */
    _cm_mode = 0;
    /* Default colormap index 0 */
    _cm_index = 0;

    ((QwtPlotCanvas*)canvas())->setLineWidth(0);
    updateLayout();

    plotLayout()->setCanvasMargin(0);
    plotLayout()->setAlignCanvasToScales(true);

    updateCanvasMargins();

    QwtPlotGrid *grid = new QwtPlotGrid;
    grid->setMajorPen(QPen(Qt::gray, 0, Qt::DotLine));
    grid->attach(this);

    setCanvasBackground(QColor(0, 0, 0));

    /* For now we always assume the low limit is 0 */
    setAxisScale(xBottom, 0, x_max);
    setAxisScale(yLeft, 0, y_max);

    d_curve = new QwtPlotSpectrogram();
    d_curve->setData( new SpectrogramData(x_max, y_max) );
    d_curve->setRenderHint(QwtPlotItem::RenderAntialiased, false);
    //d_curve->setRenderThreadCount(2);
    d_curve->setColorMap(new GISTEarthColorMap());
    d_curve->attach(this);

    const QwtInterval zInterval = d_curve->data()->interval( Qt::ZAxis );

    QwtScaleWidget *rightAxis = axisWidget(QwtPlot::yRight);
    rightAxis->setTitle("Counts");
    rightAxis->setColorBarEnabled(true);
    rightAxis->setColorMap( zInterval, new GISTEarthColorMap());

    setAxisScale(QwtPlot::yRight, zInterval.minValue(), zInterval.maxValue() );
    enableAxis(QwtPlot::yRight);

    setAutoReplot(false);

    //(void) new Zoomer(canvas(), x_max);
    _z = new Zoomer((QwtPlotCanvas*)canvas(), x_max);

    setColorMap(0);

    replot();
}

SpectroScatterPlot::~SpectroScatterPlot() {
    //delete d_curve;
}

void SpectroScatterPlot::appendPoints(const QVector<MDDASDataPoint> &v) {
    SpectrogramData *data = static_cast<SpectrogramData *>( d_curve->data() );
    data->append(v);
    // data->updateScale();

    // const QwtInterval zInterval = d_curve->data()->interval( Qt::ZAxis );

    // QwtScaleWidget *rightAxis = axisWidget(QwtPlot::yRight);
    // //rightAxis->setTitle("Intensity");
    // rightAxis->setColorBarEnabled(true);
    // rightAxis->setColorMap( zInterval, new ColorMap());

    // setAxisScale(QwtPlot::yRight, zInterval.minValue(), zInterval.maxValue() );

    //replot();
}

void SpectroScatterPlot::clear() {
    SpectrogramData *data = static_cast<SpectrogramData *>( d_curve->data() );
    data->clear();
    data->updateScale();

    /* Fake stuff to set the interval back to 0-1 */
    const QwtInterval zInterval = QwtInterval(0.1, 1);

    QwtScaleWidget *rightAxis = axisWidget(QwtPlot::yRight);
    //rightAxis->setColorBarEnabled(true);
    //rightAxis->setColorMap( zInterval, new GISTEarthColorMap());
    if (zInterval.isValid()) {
        //qDebug() << zInterval.minValue() << " " << zInterval.maxValue();
        rightAxis->setColorMap(zInterval, const_cast<QwtColorMap *>(rightAxis->colorMap()));
        //rightAxis->setColorBarInterval(zInterval);
    } else {
        //rightAxis->setColorBarInterval(QwtInterval(0.1, 1.0));
        rightAxis->setColorMap(QwtInterval(0.1, 1.0), const_cast<QwtColorMap *>(rightAxis->colorMap()));
    }

    setAxisScale(QwtPlot::yRight, 0.1, 1);

    replot();
}

QSize SpectroScatterPlot::sizeHint() const {
    return QSize(500,500);
    //return maximumSize();
}

void SpectroScatterPlot::configure(MDDASPlotConfig pc) {
    qDebug() << "deleting old data";
    delete d_curve->data();
    qDebug() << "deleted old data";
    QString str;
    str.setNum(pc.getXMax());
    qDebug() << "x max: " << str;
    d_curve->setData(new SpectrogramData(pc.getXMax(), pc.getYMax()));
    //d_curve->setColorMap(new ColorMap());
    qDebug() << "made new data";
    setAxisScale(xBottom, 0, pc.getXMax());
    setAxisScale(yLeft, 0, pc.getYMax());

    _z->setZoomBase();

    replot();
}

void SpectroScatterPlot::replotWithScale() {
    SpectrogramData *data = static_cast<SpectrogramData *>( d_curve->data() );
    data->updateScale();

    const QwtInterval zInterval = d_curve->data()->interval( Qt::ZAxis );

    QwtScaleWidget *rightAxis = axisWidget(QwtPlot::yRight);
    //rightAxis->setColorBarEnabled(true);
    //rightAxis->setColorMap( zInterval, new GISTEarthColorMap());
    if (zInterval.isValid()) {
        if (zInterval.width() == 0) {
            //rightAxis->setColorBarInterval(QwtInterval(0.1, 1));
            rightAxis->setColorMap(QwtInterval(0.1, 1), const_cast<QwtColorMap *>(rightAxis->colorMap()));
            //setAxisScale(QwtPlot::yRight, 0, 1 );
            setAxisScale(QwtPlot::yRight, 0.1, 1 );
        } else {
            //rightAxis->setColorBarInterval( zInterval);
            rightAxis->setColorMap( zInterval, const_cast<QwtColorMap *>(rightAxis->colorMap()));
            setAxisScale(QwtPlot::yRight, zInterval.minValue(), zInterval.maxValue() );
        }
    } else {
        rightAxis->setColorMap(QwtInterval(0.1, 1), const_cast<QwtColorMap *>(rightAxis->colorMap()));
        //rightAxis->setColorBarInterval(QwtInterval(0.1, 1));
        //setAxisScale(QwtPlot::yRight, 0, 1 );
        setAxisScale(QwtPlot::yRight, 0.1, 1 );
    }

    //setAxisScale(QwtPlot::yRight, zInterval.minValue(), zInterval.maxValue() );
    replot();
}

void SpectroScatterPlot::setColorMap(int cm) {
    _cm_index = cm;
    const QwtInterval zInterval = d_curve->data()->interval( Qt::ZAxis );
    QwtScaleWidget *rightAxis = axisWidget(QwtPlot::yRight);

    if (_cm_mode) {
        setAxisScaleEngine(QwtPlot::yRight, new QwtLogScaleEngine());
    } else {
        setAxisScaleEngine(QwtPlot::yRight, new QwtLinearScaleEngine());
    }

    /* Based on index of combobox in specbox.cpp */
    switch(cm) {
    case 0: {
        d_curve->setColorMap(new GISTEarthColorMap(_cm_mode));
        rightAxis->setColorMap(zInterval, new GISTEarthColorMap(_cm_mode));
        break;
    }
    case 1: {
        d_curve->setColorMap(new GISTSternColorMap(_cm_mode));
        rightAxis->setColorMap(zInterval, new GISTSternColorMap(_cm_mode));

        break;
    }
    case 2: {
        d_curve->setColorMap(new GISTHeatColorMap(_cm_mode));
        rightAxis->setColorMap(zInterval, new GISTHeatColorMap(_cm_mode));

        break;
    }
    case 3: {
        d_curve->setColorMap(new SpectroColorMap(_cm_mode));
        rightAxis->setColorMap(zInterval, new SpectroColorMap(_cm_mode));

        break;
    }
    case 4: {
        d_curve->setColorMap(new GISTGrayColorMap(_cm_mode));
        rightAxis->setColorMap(zInterval, new GISTGrayColorMap(_cm_mode));

        break;
    }
    case 5: {
        d_curve->setColorMap(new GISTYargColorMap(_cm_mode));
        rightAxis->setColorMap(zInterval, new GISTYargColorMap(_cm_mode));

        break;
    }
    case 6: {
        d_curve->setColorMap(new SpectralColorMap(_cm_mode));
        rightAxis->setColorMap(zInterval, new SpectralColorMap(_cm_mode));

        break;
    }
    case 7: {
        d_curve->setColorMap(new SpectralTwoColorMap(_cm_mode));
        rightAxis->setColorMap(zInterval, new SpectralTwoColorMap(_cm_mode));

        break;
    }
    case 8: {
        d_curve->setColorMap(new BoneColorMap(_cm_mode));
        rightAxis->setColorMap(zInterval, new BoneColorMap(_cm_mode));

        break;
    }
    case 9: {
        d_curve->setColorMap(new IshiharaColorMap(_cm_mode));
        rightAxis->setColorMap(zInterval, new IshiharaColorMap(_cm_mode));

        break;
    }
    case 10: {
        d_curve->setColorMap(new BobbyColorMap(_cm_mode));
        rightAxis->setColorMap(zInterval, new BobbyColorMap(_cm_mode));

        break;
    }
    default: {
        d_curve->setColorMap(new GISTEarthColorMap(_cm_mode));
        rightAxis->setColorMap(zInterval, new GISTEarthColorMap(_cm_mode));

        break;
    }
    }

    replotWithScale();
}

void SpectroScatterPlot::setColorMapMode(bool cm_mode) {
    if (cm_mode) {
        _cm_mode = 0;
    } else {
        _cm_mode = 1;
    }
    // if (cm_mode > 0) {
    //     _cm_mode = 1;
    // } else {
    //     _cm_mode = 0;
    // }

    setColorMap(_cm_index);
}
<commit_msg>Get rid of boundary bug, quiet some old comments<commit_after>#include <qnumeric.h>
#include <qwt_plot.h>
#include <qwt_plot_grid.h>
#include <qwt_plot_canvas.h>
#include <qwt_plot_spectrogram.h>
#include <qwt_plot_layout.h>
#include <qwt_plot_rescaler.h>
#include <qwt_color_map.h>
#include <qwt_scale_engine.h>
#include <qwt_scale_widget.h>
#include <qwt_matrix_raster_data.h>
#include <algorithm>
#include <QDebug>
#include <QColor>

#include "spectroscatterplot.h"
#include "colormaps.h"
#include "mddasplotconfig.h"
#include "mddasdatapoint.h"
#include "zoomer.h"

class SpectrogramData: public QwtMatrixRasterData {
public:
    SpectrogramData(uint x_max, uint y_max) {
        _max_v = 0;
        x_lim = x_max;
        y_lim = y_max;

        /* Create the private array */
        /* Note: this is mapped via index magic */
        this->vals = new uint[x_max*y_max];
        /* Init the private array to 0 */
        memset(vals, 0, x_max*y_max*sizeof(unsigned int));

        /* Set the axes intervals */
        setInterval( Qt::XAxis, QwtInterval( 0.0, x_max ) );
        setInterval( Qt::YAxis, QwtInterval( 0.0, y_max ) );
        setInterval( Qt::ZAxis, QwtInterval( 0.0, 1.0 ) );
    }

    ~SpectrogramData() {
        /* IMPORTANT! Delete the vals array */
        delete[] this->vals;
        //this->vals = 0;
    }

    inline void updateScale() {
        /* Update the scale to reflect the largest Z value */
        //setInterval( Qt::ZAxis, QwtInterval( 0.0, (double)*std::max_element(vals, vals + x_lim*y_lim)));
        setInterval( Qt::ZAxis, QwtInterval( 0.1, (double)_max_v));
    }

    inline void append(const QVector<MDDASDataPoint> &vec) {

        /* Append new z vals. */
        for (uint i = 0; i < (uint)vec.size(); i++) {
            if (((uint)vec[i].x() < x_lim) && ((uint)vec[i].y() < y_lim)) {
                vals[y_lim*(uint)vec[i].x() + (uint)vec[i].y()] += 1;
                /* This handles max amplitude without having to loop
                   over the entire matrix */
                if (vals[y_lim*(uint)vec[i].x() + (uint)vec[i].y()] > _max_v) {
                    _max_v += 1;
                }

            }
        }
    }

    inline QRectF pixelHint(const QRectF &area) const {
        Q_UNUSED( area )

        QRectF rect;

        const QwtInterval intervalX = interval( Qt::XAxis );
        const QwtInterval intervalY = interval( Qt::YAxis );
        if ( intervalX.isValid() && intervalY.isValid() ) {
            rect = QRectF( intervalX.minValue(), intervalY.minValue(),
                           1.0, 1.0 );
        }

        return rect;
    }

    inline void clear() {
        /* Set all values to 0. */
        memset(vals, 0, x_lim*y_lim*sizeof(unsigned int));
        /* Set max amplitude to 0 */
        _max_v = 0;
    }

    /* Overloaded value function that returns image z vals from map. */
    virtual double value(double x, double y) const {
        const QwtInterval xInterval = interval( Qt::XAxis );
        const QwtInterval yInterval = interval( Qt::YAxis );

        /* Use only data within the plot region */
        if ( !( xInterval.contains(x) && yInterval.contains(y) ) )
            return qQNaN();

        if (x < x_lim && y < y_lim) {
            return (double)vals[y_lim*(uint)x + (uint)y];
        } else {
            /* Edge case! */
            return (double)0.0;
        }

        //return (double)vals[y_lim *(uint)x + (uint)y];
    }

private:
    uint *vals; /* matrix of image z values */
    uint x_lim;
    uint y_lim;
    uint _max_v;
};

SpectroScatterPlot::SpectroScatterPlot(QWidget *parent, uint x_max, uint y_max):
    QwtPlot(parent),
    d_curve(NULL)
{
    setFrameStyle(QFrame::NoFrame);
    setLineWidth(0);
    //setCanvasLineWidth(0);

    /* Color map mode linear */
    _cm_mode = 0;
    /* Default colormap index 0 */
    _cm_index = 0;

    ((QwtPlotCanvas*)canvas())->setLineWidth(0);
    updateLayout();

    plotLayout()->setCanvasMargin(0);
    plotLayout()->setAlignCanvasToScales(true);

    updateCanvasMargins();

    QwtPlotGrid *grid = new QwtPlotGrid;
    grid->setMajorPen(QPen(Qt::gray, 0, Qt::DotLine));
    grid->attach(this);

    setCanvasBackground(QColor(0, 0, 0));

    /* For now we always assume the low limit is 0 */
    setAxisScale(xBottom, 0, x_max);
    setAxisScale(yLeft, 0, y_max);

    d_curve = new QwtPlotSpectrogram();
    d_curve->setData( new SpectrogramData(x_max, y_max) );
    d_curve->setRenderHint(QwtPlotItem::RenderAntialiased, false);
    //d_curve->setRenderThreadCount(2);
    d_curve->setColorMap(new GISTEarthColorMap());
    d_curve->attach(this);

    const QwtInterval zInterval = d_curve->data()->interval( Qt::ZAxis );

    QwtScaleWidget *rightAxis = axisWidget(QwtPlot::yRight);
    rightAxis->setTitle("Counts");
    rightAxis->setColorBarEnabled(true);
    rightAxis->setColorMap( zInterval, new GISTEarthColorMap());

    setAxisScale(QwtPlot::yRight, zInterval.minValue(), zInterval.maxValue() );
    enableAxis(QwtPlot::yRight);

    setAutoReplot(false);

    //(void) new Zoomer(canvas(), x_max);
    _z = new Zoomer((QwtPlotCanvas*)canvas(), x_max);

    setColorMap(0);

    replot();
}

SpectroScatterPlot::~SpectroScatterPlot() {
    //delete d_curve;
}

void SpectroScatterPlot::appendPoints(const QVector<MDDASDataPoint> &v) {
    SpectrogramData *data = static_cast<SpectrogramData *>( d_curve->data() );
    data->append(v);
    // data->updateScale();

    // const QwtInterval zInterval = d_curve->data()->interval( Qt::ZAxis );

    // QwtScaleWidget *rightAxis = axisWidget(QwtPlot::yRight);
    // //rightAxis->setTitle("Intensity");
    // rightAxis->setColorBarEnabled(true);
    // rightAxis->setColorMap( zInterval, new ColorMap());

    // setAxisScale(QwtPlot::yRight, zInterval.minValue(), zInterval.maxValue() );

    //replot();
}

void SpectroScatterPlot::clear() {
    SpectrogramData *data = static_cast<SpectrogramData *>( d_curve->data() );
    data->clear();
    data->updateScale();

    /* Fake stuff to set the interval back to 0-1 */
    const QwtInterval zInterval = QwtInterval(0.1, 1);

    QwtScaleWidget *rightAxis = axisWidget(QwtPlot::yRight);
    //rightAxis->setColorBarEnabled(true);
    //rightAxis->setColorMap( zInterval, new GISTEarthColorMap());
    if (zInterval.isValid()) {
        //qDebug() << zInterval.minValue() << " " << zInterval.maxValue();
        rightAxis->setColorMap(zInterval, const_cast<QwtColorMap *>(rightAxis->colorMap()));
        //rightAxis->setColorBarInterval(zInterval);
    } else {
        //rightAxis->setColorBarInterval(QwtInterval(0.1, 1.0));
        rightAxis->setColorMap(QwtInterval(0.1, 1.0), const_cast<QwtColorMap *>(rightAxis->colorMap()));
    }

    setAxisScale(QwtPlot::yRight, 0.1, 1);

    replot();
}

QSize SpectroScatterPlot::sizeHint() const {
    return QSize(500,500);
    //return maximumSize();
}

void SpectroScatterPlot::configure(MDDASPlotConfig pc) {
    // qDebug() << "specmon deleting old data";
    delete d_curve->data();
    // qDebug() << "specmon deleted old data";

    //qDebug() << "spec x max: " << pc.getXMax();
    d_curve->setData(new SpectrogramData(pc.getXMax(), pc.getYMax()));
    //d_curve->setColorMap(new ColorMap());
    //qDebug() << "specmon made new data";
    setAxisScale(xBottom, 0, pc.getXMax());
    setAxisScale(yLeft, 0, pc.getYMax());

    _z->setZoomBase();

    replot();
}

void SpectroScatterPlot::replotWithScale() {
    SpectrogramData *data = static_cast<SpectrogramData *>( d_curve->data() );
    data->updateScale();

    const QwtInterval zInterval = d_curve->data()->interval( Qt::ZAxis );

    QwtScaleWidget *rightAxis = axisWidget(QwtPlot::yRight);
    //rightAxis->setColorBarEnabled(true);
    //rightAxis->setColorMap( zInterval, new GISTEarthColorMap());
    if (zInterval.isValid()) {
        if (zInterval.width() == 0) {
            //rightAxis->setColorBarInterval(QwtInterval(0.1, 1));
            rightAxis->setColorMap(QwtInterval(0.1, 1), const_cast<QwtColorMap *>(rightAxis->colorMap()));
            //setAxisScale(QwtPlot::yRight, 0, 1 );
            setAxisScale(QwtPlot::yRight, 0.1, 1 );
        } else {
            //rightAxis->setColorBarInterval( zInterval);
            rightAxis->setColorMap( zInterval, const_cast<QwtColorMap *>(rightAxis->colorMap()));
            setAxisScale(QwtPlot::yRight, zInterval.minValue(), zInterval.maxValue() );
        }
    } else {
        rightAxis->setColorMap(QwtInterval(0.1, 1), const_cast<QwtColorMap *>(rightAxis->colorMap()));
        //rightAxis->setColorBarInterval(QwtInterval(0.1, 1));
        //setAxisScale(QwtPlot::yRight, 0, 1 );
        setAxisScale(QwtPlot::yRight, 0.1, 1 );
    }

    //setAxisScale(QwtPlot::yRight, zInterval.minValue(), zInterval.maxValue() );
    replot();
}

void SpectroScatterPlot::setColorMap(int cm) {
    _cm_index = cm;
    const QwtInterval zInterval = d_curve->data()->interval( Qt::ZAxis );
    QwtScaleWidget *rightAxis = axisWidget(QwtPlot::yRight);

    if (_cm_mode) {
        setAxisScaleEngine(QwtPlot::yRight, new QwtLogScaleEngine());
    } else {
        setAxisScaleEngine(QwtPlot::yRight, new QwtLinearScaleEngine());
    }

    /* Based on index of combobox in specbox.cpp */
    switch(cm) {
    case 0: {
        d_curve->setColorMap(new GISTEarthColorMap(_cm_mode));
        rightAxis->setColorMap(zInterval, new GISTEarthColorMap(_cm_mode));
        break;
    }
    case 1: {
        d_curve->setColorMap(new GISTSternColorMap(_cm_mode));
        rightAxis->setColorMap(zInterval, new GISTSternColorMap(_cm_mode));

        break;
    }
    case 2: {
        d_curve->setColorMap(new GISTHeatColorMap(_cm_mode));
        rightAxis->setColorMap(zInterval, new GISTHeatColorMap(_cm_mode));

        break;
    }
    case 3: {
        d_curve->setColorMap(new SpectroColorMap(_cm_mode));
        rightAxis->setColorMap(zInterval, new SpectroColorMap(_cm_mode));

        break;
    }
    case 4: {
        d_curve->setColorMap(new GISTGrayColorMap(_cm_mode));
        rightAxis->setColorMap(zInterval, new GISTGrayColorMap(_cm_mode));

        break;
    }
    case 5: {
        d_curve->setColorMap(new GISTYargColorMap(_cm_mode));
        rightAxis->setColorMap(zInterval, new GISTYargColorMap(_cm_mode));

        break;
    }
    case 6: {
        d_curve->setColorMap(new SpectralColorMap(_cm_mode));
        rightAxis->setColorMap(zInterval, new SpectralColorMap(_cm_mode));

        break;
    }
    case 7: {
        d_curve->setColorMap(new SpectralTwoColorMap(_cm_mode));
        rightAxis->setColorMap(zInterval, new SpectralTwoColorMap(_cm_mode));

        break;
    }
    case 8: {
        d_curve->setColorMap(new BoneColorMap(_cm_mode));
        rightAxis->setColorMap(zInterval, new BoneColorMap(_cm_mode));

        break;
    }
    case 9: {
        d_curve->setColorMap(new IshiharaColorMap(_cm_mode));
        rightAxis->setColorMap(zInterval, new IshiharaColorMap(_cm_mode));

        break;
    }
    case 10: {
        d_curve->setColorMap(new BobbyColorMap(_cm_mode));
        rightAxis->setColorMap(zInterval, new BobbyColorMap(_cm_mode));

        break;
    }
    default: {
        d_curve->setColorMap(new GISTEarthColorMap(_cm_mode));
        rightAxis->setColorMap(zInterval, new GISTEarthColorMap(_cm_mode));

        break;
    }
    }

    replotWithScale();
}

void SpectroScatterPlot::setColorMapMode(bool cm_mode) {
    if (cm_mode) {
        _cm_mode = 0;
    } else {
        _cm_mode = 1;
    }
    // if (cm_mode > 0) {
    //     _cm_mode = 1;
    // } else {
    //     _cm_mode = 0;
    // }

    setColorMap(_cm_index);
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: viewfac.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-07 17:23:37 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library 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 library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef _VIEWFAC_HXX
#define _VIEWFAC_HXX

#ifndef _SAL_CONFIG_H_
#include "sal/config.h"
#endif

#ifndef INCLUDED_SFX2_DLLAPI_H
#include "sfx2/dllapi.h"
#endif

#ifndef _STRING_HXX //autogen
#include <tools/string.hxx>
#endif
#ifndef _RESID_HXX //autogen
#include <tools/resid.hxx>
#endif

class SfxViewFrame;
class SfxViewShell;
class Window;

typedef SfxViewShell* (*SfxViewCtor)(SfxViewFrame*, SfxViewShell*);
typedef void (*SfxViewInit)();

// CLASS -----------------------------------------------------------------
class SFX2_DLLPUBLIC SfxViewFactory
{
public:
    SfxViewFactory( SfxViewCtor fnC, SfxViewInit fnI,
                    USHORT nOrdinal, const ResId& aDescrResId );
    ~SfxViewFactory();

    SfxViewShell *CreateInstance(SfxViewFrame *pViewFrame, SfxViewShell *pOldSh);
    void          InitFactory();

    String        GetDescription() const
                  { return String( aDescription ); }
    USHORT        GetOrdinal() const { return nOrd; }

private:
    SfxViewCtor fnCreate;
    SfxViewInit fnInit;
    USHORT      nOrd;
    ResId       aDescription;
};

#endif

<commit_msg>INTEGRATION: CWS changefileheader (1.4.732); FILE MERGED 2008/04/01 15:38:18 thb 1.4.732.3: #i85898# Stripping all external header guards 2008/04/01 12:40:33 thb 1.4.732.2: #i85898# Stripping all external header guards 2008/03/31 13:37:54 rt 1.4.732.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: viewfac.hxx,v $
 * $Revision: 1.5 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org 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.
 *
 * OpenOffice.org 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
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/
#ifndef _VIEWFAC_HXX
#define _VIEWFAC_HXX

#include "sal/config.h"
#include "sfx2/dllapi.h"
#include <tools/string.hxx>
#ifndef _RESID_HXX //autogen
#include <tools/resid.hxx>
#endif

class SfxViewFrame;
class SfxViewShell;
class Window;

typedef SfxViewShell* (*SfxViewCtor)(SfxViewFrame*, SfxViewShell*);
typedef void (*SfxViewInit)();

// CLASS -----------------------------------------------------------------
class SFX2_DLLPUBLIC SfxViewFactory
{
public:
    SfxViewFactory( SfxViewCtor fnC, SfxViewInit fnI,
                    USHORT nOrdinal, const ResId& aDescrResId );
    ~SfxViewFactory();

    SfxViewShell *CreateInstance(SfxViewFrame *pViewFrame, SfxViewShell *pOldSh);
    void          InitFactory();

    String        GetDescription() const
                  { return String( aDescription ); }
    USHORT        GetOrdinal() const { return nOrd; }

private:
    SfxViewCtor fnCreate;
    SfxViewInit fnInit;
    USHORT      nOrd;
    ResId       aDescription;
};

#endif

<|endoftext|>


<commit_before>/*
 @ 0xCCCCCCCC
*/

#include "kbase\logging.h"

#include <Windows.h>

#include <algorithm>
#include <cassert>
#include <cstdio>
#include <ctime>
#include <iomanip>
#include <memory>
#include <mutex>
#include <stdexcept>

#include "kbase\basic_types.h"
#include "kbase\error_exception_util.h"
#include "kbase\scoped_handle.h"

namespace {

using kbase::LogSeverity;
using kbase::LogItemOptions;
using kbase::LoggingDestination;
using kbase::LoggingLockOption;
using kbase::OldFileDisposalOption;

using kbase::PathChar;
using kbase::PathString;
using kbase::ScopedStdioHandle;

using GlobalLockHandle = kbase::ScopedSysHandle;
using ThreadLockHandle = std::unique_ptr<std::unique_lock<std::mutex>>;

const char* kLogSeverityNames[] {"INFO", "WARNING", "ERROR", "FATAL"};

const LogSeverity kAlwaysPrintErrorMinLevel = LogSeverity::LOG_ERROR;

LogSeverity g_min_severity_level = LogSeverity::LOG_INFO;
LogItemOptions g_log_item_options = LogItemOptions::ENABLE_TIMESTAMP;
LoggingDestination g_logging_dest = LoggingDestination::LOG_TO_FILE;
OldFileDisposalOption g_old_file_option = OldFileDisposalOption::APPEND_TO_OLD_LOG_FILE;
LoggingLockOption g_logging_lock_option = LoggingLockOption::USE_GLOBAL_LOCK;

ScopedStdioHandle g_log_file;

const PathChar kLogFileName[] = L"_debug_message.log";

template<typename E>
constexpr auto ToUnderlying(E e)
{
    return static_cast<std::underlying_type_t<E>>(e);
}

// Due to the performance consideration, I decide not to use std::string and
// neither StringPiece, since I also want to keep this file more independent
// as possible
template<typename charT>
const charT* ExtractFileName(const charT* file_path)
{
    const charT* p = file_path;
    const charT* last_pos = nullptr;
    for (; *p != '\0'; ++p) {
        if (*p == '/' || *p == '\\') {
            last_pos = p;
        }
    }

    return last_pos ? last_pos + 1 : file_path;
}

// Returns the path of default log file.
// We use the same path as the EXE file.
PathString GetDefaultLogFile()
{
    PathChar exe_path[MAX_PATH];
    GetModuleFileName(nullptr, exe_path, MAX_PATH);

    const PathChar* end_past_slash = ExtractFileName(exe_path);
    const PathChar* ext_dot = std::find(end_past_slash, std::cend(exe_path), L'.');

    PathString default_path(const_cast<const PathChar*>(exe_path), end_past_slash);
    default_path.append(end_past_slash, ext_dot);
    default_path.append(kLogFileName);

    return default_path;
}

// This function needs an global mutex-like protector that has this call enclosed.
// We can have multiple threads and/or processes, try to prevent messing up each
// other's writes.
// Returns true, if the file is ready to write; return false, otherwise.
bool InitLogFile()
{
    PathString&& log_file_name = GetDefaultLogFile();

    if (g_old_file_option == OldFileDisposalOption::DELETE_OLD_LOG_FILE) {
        if (g_log_file) {
            g_log_file = nullptr;
        }

        _wremove(log_file_name.c_str());
    }

    if (g_log_file) {
        return true;
    }

    g_log_file.Reset(_wfsopen(log_file_name.c_str(), L"a", _SH_DENYNO));

    if (!g_log_file) {
        return false;
    }

    return true;
}

// A well-tailored lock for resolving race-condition when multiple threads or even
// multiple processes are logging to the file simultanesouly.
class LoggingLock {
public:
    LoggingLock()
    {
        Lock();
    }

    ~LoggingLock()
    {
        Unlock();
    }

    // This function should be called on the main thread before any logging.
    static void InitLock()
    {
        if (initialized_) {
            return;
        }

        if (g_logging_lock_option == LoggingLockOption::USE_GLOBAL_LOCK) {
            PathString log_name = GetDefaultLogFile();
            // We want the file name to be part of the mutex name, and \ is not a
            // legal character, so we replace \ with /.
            std::replace(log_name.begin(), log_name.end(), L'\\', L'/');

            std::wstring mutex_name = L"Global\\";
            mutex_name.append(log_name);

            // If the mutex has alread been created by another thread or process
            // this call returns the handle to the existed mutex
            global_lock_.Reset(CreateMutexW(nullptr, false, mutex_name.c_str()));
            if (!global_lock_) {
#if _DEBUG
                kbase::LastError error;
                assert(false);
#endif
                return;
            }
        } else {
            local_lock_.reset(
                new std::unique_lock<std::mutex>(local_mutex_, std::defer_lock));
        }

        initialized_ = true;
    }

private:
    LoggingLock(const LoggingLock&) = delete;
    LoggingLock& operator=(const LoggingLock&) = delete;

    void Lock()
    {
        if (g_logging_lock_option == LoggingLockOption::USE_GLOBAL_LOCK) {
            WaitForSingleObject(global_lock_, INFINITE);
        } else {
            local_lock_->lock();
        }
    }

    void Unlock()
    {
        if (g_logging_lock_option == LoggingLockOption::USE_GLOBAL_LOCK) {
            ReleaseMutex(global_lock_);
        } else {
            local_lock_->unlock();
        }
    }

private:
    static bool initialized_;
    static GlobalLockHandle global_lock_;
    static ThreadLockHandle local_lock_;
    static std::mutex local_mutex_;
};

bool LoggingLock::initialized_ = false;
GlobalLockHandle LoggingLock::global_lock_;
ThreadLockHandle LoggingLock::local_lock_;
std::mutex LoggingLock::local_mutex_;

}   // namespace

namespace kbase {

namespace internal {

LogSeverity GetMinSeverityLevel()
{
    return g_min_severity_level;
}

}   // namespace internal

LoggingSettings::LoggingSettings()
 : min_severity_level(LogSeverity::LOG_INFO),
   log_item_options(LogItemOptions::ENABLE_TIMESTAMP),
   logging_destination(LoggingDestination::LOG_TO_FILE),
   old_file_disposal_option(OldFileDisposalOption::APPEND_TO_OLD_LOG_FILE),
   logging_lock_option(LoggingLockOption::USE_GLOBAL_LOCK)
{}

void ConfigureLoggingSettings(const LoggingSettings& settings)
{
    g_min_severity_level = settings.min_severity_level;
    g_log_item_options = settings.log_item_options;
    g_logging_dest = settings.logging_destination;
    g_old_file_option = settings.old_file_disposal_option;
    g_logging_lock_option = settings.logging_lock_option;

    LoggingLock::InitLock();
}

LogMessage::LogMessage(const char* file, int line, LogSeverity severity)
 : file_(file), line_(line), severity_(severity)
{
    Init(file, line);
}

LogMessage::LogMessage(const char* file, int line)
 : LogMessage(file, line, LogSeverity::LOG_INFO)
{}

LogMessage::~LogMessage()
{
#if _DEBUG
    if (severity_ == LogSeverity::LOG_FATAL) {
        // TODO: log stack trace information
    }
#endif

    stream_ << std::endl;
    std::string msg = stream_.str();

    if ((g_logging_dest & LoggingDestination::LOG_TO_SYSTEM_DEBUG_LOG) ||
        (severity_ >= kAlwaysPrintErrorMinLevel)) {
        OutputDebugStringA(msg.c_str());
    }

    if (g_logging_dest & LoggingDestination::LOG_TO_FILE) {
        LoggingLock::InitLock();
        LoggingLock lock;
        if (InitLogFile()) {
            fwrite(static_cast<const void*>(msg.c_str()), sizeof(char), msg.length(),
                   g_log_file);
            fflush(g_log_file);
        }
    }
}

void LogMessage::Init(const char* file, int line)
{
    stream_ << "[";

    if (g_log_item_options & LogItemOptions::ENABLE_PROCESS_ID) {
        stream_ << GetCurrentProcessId() << ":";
    }

    if (g_log_item_options & LogItemOptions::ENABLE_THREAD_ID) {
        stream_ << GetCurrentThreadId() << ":";
    }

    if (g_log_item_options & LogItemOptions::ENABLE_TIMESTAMP) {
        time_t time_now = time(nullptr);
        struct tm local_time_now;
        localtime_s(&local_time_now, &time_now);

        stream_ << std::setfill('0')
                << std::setw(2) << 1 + local_time_now.tm_mon
                << std::setw(2) << local_time_now.tm_mday
                << '/'
                << std::setw(2) << local_time_now.tm_hour
                << std::setw(2) << local_time_now.tm_min
                << std::setw(2) << local_time_now.tm_sec
                << ':';
    }

    stream_ << kLogSeverityNames[ToUnderlying(severity_)];

    const char* file_name = ExtractFileName(file);

    stream_ << ':' << file_name << '(' << line << ")]";
}

}   // namespace kbase<commit_msg>Logging: write log messages to stderr when current severity is higher or equal to `kAlwaysPrintErrorMinLevel`.<commit_after>/*
 @ 0xCCCCCCCC
*/

#include "kbase\logging.h"

#include <Windows.h>

#include <algorithm>
#include <cassert>
#include <cstdio>
#include <ctime>
#include <iomanip>
#include <memory>
#include <mutex>
#include <stdexcept>

#include "kbase\basic_types.h"
#include "kbase\error_exception_util.h"
#include "kbase\scoped_handle.h"

namespace {

using kbase::LogSeverity;
using kbase::LogItemOptions;
using kbase::LoggingDestination;
using kbase::LoggingLockOption;
using kbase::OldFileDisposalOption;

using kbase::PathChar;
using kbase::PathString;
using kbase::ScopedStdioHandle;

using GlobalLockHandle = kbase::ScopedSysHandle;
using ThreadLockHandle = std::unique_ptr<std::unique_lock<std::mutex>>;

const char* kLogSeverityNames[] {"INFO", "WARNING", "ERROR", "FATAL"};

const LogSeverity kAlwaysPrintErrorMinLevel = LogSeverity::LOG_ERROR;

LogSeverity g_min_severity_level = LogSeverity::LOG_INFO;
LogItemOptions g_log_item_options = LogItemOptions::ENABLE_TIMESTAMP;
LoggingDestination g_logging_dest = LoggingDestination::LOG_TO_FILE;
OldFileDisposalOption g_old_file_option = OldFileDisposalOption::APPEND_TO_OLD_LOG_FILE;
LoggingLockOption g_logging_lock_option = LoggingLockOption::USE_GLOBAL_LOCK;

ScopedStdioHandle g_log_file;

const PathChar kLogFileName[] = L"_debug_message.log";

template<typename E>
constexpr auto ToUnderlying(E e)
{
    return static_cast<std::underlying_type_t<E>>(e);
}

// Due to the performance consideration, I decide not to use std::string and
// neither StringPiece, since I also want to keep this file more independent
// as possible
template<typename charT>
const charT* ExtractFileName(const charT* file_path)
{
    const charT* p = file_path;
    const charT* last_pos = nullptr;
    for (; *p != '\0'; ++p) {
        if (*p == '/' || *p == '\\') {
            last_pos = p;
        }
    }

    return last_pos ? last_pos + 1 : file_path;
}

// Returns the path of default log file.
// We use the same path as the EXE file.
PathString GetDefaultLogFile()
{
    PathChar exe_path[MAX_PATH];
    GetModuleFileName(nullptr, exe_path, MAX_PATH);

    const PathChar* end_past_slash = ExtractFileName(exe_path);
    const PathChar* ext_dot = std::find(end_past_slash, std::cend(exe_path), L'.');

    PathString default_path(const_cast<const PathChar*>(exe_path), end_past_slash);
    default_path.append(end_past_slash, ext_dot);
    default_path.append(kLogFileName);

    return default_path;
}

// This function needs an global mutex-like protector that has this call enclosed.
// We can have multiple threads and/or processes, try to prevent messing up each
// other's writes.
// Returns true, if the file is ready to write; return false, otherwise.
bool InitLogFile()
{
    PathString&& log_file_name = GetDefaultLogFile();

    if (g_old_file_option == OldFileDisposalOption::DELETE_OLD_LOG_FILE) {
        if (g_log_file) {
            g_log_file = nullptr;
        }

        _wremove(log_file_name.c_str());
    }

    if (g_log_file) {
        return true;
    }

    g_log_file.Reset(_wfsopen(log_file_name.c_str(), L"a", _SH_DENYNO));

    if (!g_log_file) {
        return false;
    }

    return true;
}

// A well-tailored lock for resolving race-condition when multiple threads or even
// multiple processes are logging to the file simultanesouly.
class LoggingLock {
public:
    LoggingLock()
    {
        Lock();
    }

    ~LoggingLock()
    {
        Unlock();
    }

    // This function should be called on the main thread before any logging.
    static void InitLock()
    {
        if (initialized_) {
            return;
        }

        if (g_logging_lock_option == LoggingLockOption::USE_GLOBAL_LOCK) {
            PathString log_name = GetDefaultLogFile();
            // We want the file name to be part of the mutex name, and \ is not a
            // legal character, so we replace \ with /.
            std::replace(log_name.begin(), log_name.end(), L'\\', L'/');

            std::wstring mutex_name = L"Global\\";
            mutex_name.append(log_name);

            // If the mutex has alread been created by another thread or process
            // this call returns the handle to the existed mutex
            global_lock_.Reset(CreateMutexW(nullptr, false, mutex_name.c_str()));
            if (!global_lock_) {
#if _DEBUG
                kbase::LastError error;
                assert(false);
#endif
                return;
            }
        } else {
            local_lock_.reset(
                new std::unique_lock<std::mutex>(local_mutex_, std::defer_lock));
        }

        initialized_ = true;
    }

private:
    LoggingLock(const LoggingLock&) = delete;
    LoggingLock& operator=(const LoggingLock&) = delete;

    void Lock()
    {
        if (g_logging_lock_option == LoggingLockOption::USE_GLOBAL_LOCK) {
            WaitForSingleObject(global_lock_, INFINITE);
        } else {
            local_lock_->lock();
        }
    }

    void Unlock()
    {
        if (g_logging_lock_option == LoggingLockOption::USE_GLOBAL_LOCK) {
            ReleaseMutex(global_lock_);
        } else {
            local_lock_->unlock();
        }
    }

private:
    static bool initialized_;
    static GlobalLockHandle global_lock_;
    static ThreadLockHandle local_lock_;
    static std::mutex local_mutex_;
};

bool LoggingLock::initialized_ = false;
GlobalLockHandle LoggingLock::global_lock_;
ThreadLockHandle LoggingLock::local_lock_;
std::mutex LoggingLock::local_mutex_;

}   // namespace

namespace kbase {

namespace internal {

LogSeverity GetMinSeverityLevel()
{
    return g_min_severity_level;
}

}   // namespace internal

LoggingSettings::LoggingSettings()
 : min_severity_level(LogSeverity::LOG_INFO),
   log_item_options(LogItemOptions::ENABLE_TIMESTAMP),
   logging_destination(LoggingDestination::LOG_TO_FILE),
   old_file_disposal_option(OldFileDisposalOption::APPEND_TO_OLD_LOG_FILE),
   logging_lock_option(LoggingLockOption::USE_GLOBAL_LOCK)
{}

void ConfigureLoggingSettings(const LoggingSettings& settings)
{
    g_min_severity_level = settings.min_severity_level;
    g_log_item_options = settings.log_item_options;
    g_logging_dest = settings.logging_destination;
    g_old_file_option = settings.old_file_disposal_option;
    g_logging_lock_option = settings.logging_lock_option;

    LoggingLock::InitLock();
}

LogMessage::LogMessage(const char* file, int line, LogSeverity severity)
 : file_(file), line_(line), severity_(severity)
{
    Init(file, line);
}

LogMessage::LogMessage(const char* file, int line)
 : LogMessage(file, line, LogSeverity::LOG_INFO)
{}

LogMessage::~LogMessage()
{
#if _DEBUG
    if (severity_ == LogSeverity::LOG_FATAL) {
        // TODO: log stack trace information
    }
#endif

    stream_ << std::endl;
    std::string msg = stream_.str();

    if (g_logging_dest & LoggingDestination::LOG_TO_SYSTEM_DEBUG_LOG) {
        OutputDebugStringA(msg.c_str());
    }

    if (severity_ >= kAlwaysPrintErrorMinLevel) {
        fwrite(msg.c_str(), sizeof(char), msg.length(), stderr);
        fflush(stderr);
    }

    if (g_logging_dest & LoggingDestination::LOG_TO_FILE) {
        LoggingLock::InitLock();
        LoggingLock lock;
        if (InitLogFile()) {
            fwrite(static_cast<const void*>(msg.c_str()), sizeof(char), msg.length(),
                   g_log_file);
            fflush(g_log_file);
        }
    }
}

void LogMessage::Init(const char* file, int line)
{
    stream_ << "[";

    if (g_log_item_options & LogItemOptions::ENABLE_PROCESS_ID) {
        stream_ << GetCurrentProcessId() << ":";
    }

    if (g_log_item_options & LogItemOptions::ENABLE_THREAD_ID) {
        stream_ << GetCurrentThreadId() << ":";
    }

    if (g_log_item_options & LogItemOptions::ENABLE_TIMESTAMP) {
        time_t time_now = time(nullptr);
        struct tm local_time_now;
        localtime_s(&local_time_now, &time_now);

        stream_ << std::setfill('0')
                << std::setw(2) << 1 + local_time_now.tm_mon
                << std::setw(2) << local_time_now.tm_mday
                << '/'
                << std::setw(2) << local_time_now.tm_hour
                << std::setw(2) << local_time_now.tm_min
                << std::setw(2) << local_time_now.tm_sec
                << ':';
    }

    stream_ << kLogSeverityNames[ToUnderlying(severity_)];

    const char* file_name = ExtractFileName(file);

    stream_ << ':' << file_name << '(' << line << ")]";
}

}   // namespace kbase<|endoftext|>


<commit_before><commit_msg>- removed wait_for_event() since it was #ifed out anyway.  I haven't   studied WHY it was removed.<commit_after><|endoftext|>


<commit_before>//
//  AHDFH.cpp
//  CS100
//
//  Created by Ammar Rizvi on 5/12/16.
//  Copyright © 2016 Ammar Rizvi. All rights reserved.
//

#include "AHDFH.hpp"
#include <iostream>
#include <vector>
#include <list>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <string.h>
#include <netdb.h>
#include <pwd.h>
#include <sys/socket.h>
//#include <boost/algorithm/string.hpp>

using namespace std;
//using namespace boost::algorithm;

// Virtual Base Class
class Base{
public:
    Base(){};
    // Virtual Function that will be inherited
    virtual bool evaluate() = 0;
};

int main () {

    //take user input
    string initialCommand = "";
    while (true) {
        string login = getlogin();
        char hostname[100];
        gethostname(hostname, 100);
        cout << "[" << login << "@" << hostname << "] $ ";
        getline(cin, initialCommand);
        trim(initialCommand);

    }

    return 0;
}
<commit_msg>Update main.cpp<commit_after>#include <iostream>
#include <vector>
#include <list>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <string.h>
#include <netdb.h>
#include <pwd.h>
#include <sys/socket.h>
#include <boost/algorithm/string.hpp>

using namespace std;
using namespace boost::algorithm;

class Base{
    public:
        Base(){};
        virtual bool evaluate() = 0;
};

class Command: public Base{
    private:
        vector<string> commandVec;
    public:
        Command(vector<string>s){
            commandVec = s;
        }

};

int main () {

    //take user input
    string initialCommand = "";
    while (true) {
        string login = getlogin();
        char hostname[100];
        gethostname(hostname, 100);
        cout << "[" << login << "@" << hostname << "] $ ";
        getline(cin, initialCommand);
        trim(initialCommand);

    }

    return 0;
}
<|endoftext|>


<commit_before>void Hlib()
{
  gSystem->Load("libPhysics.so");
  gSystem->Load("libMinuit.so");

  gSystem->Load("libEG");
  gSystem->Load("libGeom");
  gSystem->Load("libVMC");

  gSystem->Load("libEGPythia6");

  gSystem->Load("libNet");
  gSystem->Load("libTree");

  gSystem->Load("libSTEERBase");
  gSystem->Load("libESD");
  gSystem->Load("libCDB");

  gSystem->Load("libRAWDatabase");
  gSystem->Load("libRAWDatarec");

  gSystem->Load("libSTEER");

  gSystem->Load("libRAWDatasim");

  gSystem->Load("libHMPIDbase.so");
  gSystem->Load("libHMPIDsim.so");
  gSystem->Load("libHMPIDrec.so");

  gSystem->AddIncludePath("-I$ALICE_ROOT/include -I$ALICE_ROOT/HMPID");
}

<commit_msg>minors<commit_after>void Hlib()
{
  gSystem->Load("libPhysics.so");
  gSystem->Load("libMinuit.so");

  gSystem->Load("libEG");
  gSystem->Load("libGeom");
  gSystem->Load("libVMC");

  gSystem->Load("libEGPythia6");

  gSystem->Load("libNet");
  gSystem->Load("libTree");

  gSystem->Load("libProof");
  gSystem->Load("libSTEERBase");
  gSystem->Load("libESD");
  gSystem->Load("libCDB");

  gSystem->Load("libRAWDatabase");
  gSystem->Load("libRAWDatarec");

  gSystem->Load("libSTEER");

  gSystem->Load("libRAWDatasim");

  gSystem->Load("libHMPIDbase.so");
  gSystem->Load("libHMPIDsim.so");
  gSystem->Load("libHMPIDrec.so");

  gSystem->AddIncludePath("-I$ALICE_ROOT/include -I$ALICE_ROOT/HMPID");
}

<|endoftext|>