Toshihiro Shimizu 890ddd
#include "toonzqt/combohistogram.h"
Toshihiro Shimizu 890ddd
#include "tcolorstyles.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include <qvboxlayout></qvboxlayout>
Toshihiro Shimizu 890ddd
#include <qgridlayout></qgridlayout>
Toshihiro Shimizu 890ddd
#include <qcombobox></qcombobox>
Toshihiro Shimizu 890ddd
#include <qstackedwidget></qstackedwidget>
Toshihiro Shimizu 890ddd
#include <qpainter></qpainter>
Toshihiro Shimizu 890ddd
#include <qlabel></qlabel>
Toshihiro Shimizu 890ddd
#include <qstring></qstring>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "toonz/preferences.h"
shun-iwasawa ad7711
#include "toonzqt/lutcalibrator.h"
Kite 521c84
#include "toonzqt/gutil.h"
shun-iwasawa d5045c
#include "timagecache.h"
shun-iwasawa d5045c
#include "trasterimage.h"
shun-iwasawa d5045c
shun-iwasawa d5045c
// TnzBase includes
shun-iwasawa d5045c
#include "tenv.h"
shun-iwasawa d5045c
Toshihiro Shimizu 890ddd
#include <qpushbutton></qpushbutton>
Toshihiro Shimizu 890ddd
#include <qdialog></qdialog>
Toshihiro Shimizu 890ddd
shun-iwasawa d5045c
TEnv::IntVar HistogramChannelDisplayMode(
shun-iwasawa d5045c
    "HistogramChannelDisplayMode",
shun-iwasawa d5045c
    (int)ComboHistoRGBLabel::Display_8bit);  // 8bit display by default
shun-iwasawa d5045c
shun-iwasawa d5045c
namespace {
shun-iwasawa d5045c
shun-iwasawa d5045c
inline int idx(int y, int x) { return y * COMBOHIST_RESOLUTION_W + x; }
shun-iwasawa d5045c
shun-iwasawa d5045c
}  // namespace
shun-iwasawa d5045c
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// ChannelHistoGraph
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
shun-iwasawa d5045c
ChannelHistoGraph::ChannelHistoGraph(int index, QWidget *parent,
shun-iwasawa d5045c
                                     bool *showComparePtr)
shun-iwasawa d5045c
    : QWidget(parent)
shun-iwasawa d5045c
    , m_showComparePtr(showComparePtr)
shun-iwasawa d5045c
    , m_channelIndex(index)
shun-iwasawa d5045c
    , m_pickedValue(-1) {
Shinya Kitaoka 120a6e
  // width 256+2 pixels, height 100+2 pixels (with margin)
Shinya Kitaoka 120a6e
  setFixedSize(COMBOHIST_RESOLUTION_W + 2, COMBOHIST_RESOLUTION_H + 2);
shun-iwasawa d5045c
  m_values[0].reserve(COMBOHIST_RESOLUTION_W);
shun-iwasawa d5045c
  m_values[1].reserve(COMBOHIST_RESOLUTION_W);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
shun-iwasawa d5045c
ChannelHistoGraph::~ChannelHistoGraph() {
shun-iwasawa d5045c
  m_values[0].clear();
shun-iwasawa d5045c
  m_values[1].clear();
shun-iwasawa d5045c
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
shun-iwasawa d5045c
void ChannelHistoGraph::setValues(int *buf, bool isComp) {
shun-iwasawa d5045c
  int id = (isComp) ? 1 : 0;
shun-iwasawa d5045c
  m_values[id].clear();
shun-iwasawa d5045c
  m_values[id].resize(COMBOHIST_RESOLUTION_W);
shun-iwasawa d5045c
  m_maxValue[id] = 1;
Shinya Kitaoka 120a6e
  int i;
Shinya Kitaoka 120a6e
  // normalize with the maximum value
Shinya Kitaoka 120a6e
  int maxValue = 1;
Shinya Kitaoka 120a6e
  for (i = 0; i < COMBOHIST_RESOLUTION_W; i++) {
shun-iwasawa d5045c
    m_values[id][i] = buf[i];
shun-iwasawa d5045c
    if (m_maxValue[id] < buf[i]) m_maxValue[id] = buf[i];
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
shun-iwasawa d5045c
  // for (i = 0; i < COMBOHIST_RESOLUTION_W; i++) {
shun-iwasawa d5045c
  //  int v = buf[i];
shun-iwasawa d5045c
  //  m_values[id][i] =
shun-iwasawa d5045c
  //      tround((double)(v * COMBOHIST_RESOLUTION_H) / (double)maxValue);
shun-iwasawa d5045c
  //}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void ChannelHistoGraph::paintEvent(QPaintEvent *event) {
Shinya Kitaoka 120a6e
  QPainter p(this);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  p.setPen(QColor(144, 144, 144));
Shinya Kitaoka 120a6e
  p.setBrush(QColor(214, 214, 214));
Shinya Kitaoka 120a6e
  p.drawRect(rect().x(), rect().y(), rect().width() - 1, rect().height() - 1);
Shinya Kitaoka 120a6e
  p.setBrush(Qt::NoBrush);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int i;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // draw scale marks
shun-iwasawa 481b59
  if (areAlmostEqual(m_range, 1.)) {
shun-iwasawa 481b59
    p.setPen(QColor(144, 144, 144));
shun-iwasawa 481b59
    for (i = 1; i < 10; i++) {
shun-iwasawa 481b59
      int posx = rect().width() * i / 10;
shun-iwasawa 481b59
      p.drawLine(posx, 1, posx, COMBOHIST_RESOLUTION_H);
shun-iwasawa 481b59
    }
shun-iwasawa 481b59
  } else {
shun-iwasawa 481b59
    int range_i = (int)std::round(m_range);
shun-iwasawa 481b59
    for (i = 1; i < range_i; i++) {
shun-iwasawa 481b59
      int posx = rect().width() * i / range_i;
shun-iwasawa 481b59
      p.drawLine(posx, 1, posx, COMBOHIST_RESOLUTION_H);
shun-iwasawa 481b59
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
shun-iwasawa 2cda63
  QColor compColor = (m_channelIndex == 0)   ? Qt::red
shun-iwasawa 2cda63
                     : (m_channelIndex == 1) ? Qt::green
shun-iwasawa 2cda63
                     : (m_channelIndex == 2) ? Qt::blue
shun-iwasawa 2cda63
                                             : Qt::magenta;
shun-iwasawa d5045c
  compColor.setAlpha(120);
Shinya Kitaoka 120a6e
shun-iwasawa d5045c
  int maxValue = m_maxValue[0];
shun-iwasawa d5045c
  if (!m_values[1].isEmpty() && m_showComparePtr && *m_showComparePtr &&
shun-iwasawa d5045c
      m_maxValue[0] < m_maxValue[1])
shun-iwasawa d5045c
    maxValue = m_maxValue[1];
Shinya Kitaoka 120a6e
shun-iwasawa d5045c
  p.translate(0, COMBOHIST_RESOLUTION_H);
shun-iwasawa d5045c
  p.scale(1.0, -(double)COMBOHIST_RESOLUTION_H / (double)maxValue);
Shinya Kitaoka 120a6e
shun-iwasawa d5045c
  for (int id = 0; id < 2; id++) {
shun-iwasawa d5045c
    if (m_values[id].isEmpty()) continue;
shun-iwasawa d5045c
    if (id == 1 && (!m_showComparePtr || !(*m_showComparePtr))) continue;
shun-iwasawa d5045c
shun-iwasawa d5045c
    p.setPen((id == 0) ? Qt::black : compColor);
shun-iwasawa d5045c
shun-iwasawa d5045c
    // draw each histogram
shun-iwasawa d5045c
    for (i = 0; i < COMBOHIST_RESOLUTION_W; i++) {
shun-iwasawa d5045c
      int v = m_values[id][i];
shun-iwasawa d5045c
      if (v <= 0) continue;
shun-iwasawa d5045c
      int x = 1 + i;
shun-iwasawa d5045c
      p.drawLine(x, 0, x, v);
shun-iwasawa d5045c
    }
shun-iwasawa d5045c
shun-iwasawa d5045c
    // draw picked color's channel value
shun-iwasawa d5045c
    if (m_pickedValue > -1) {
shun-iwasawa d5045c
      p.setPen(Qt::white);
shun-iwasawa d5045c
      int x = 1 + m_pickedValue;
shun-iwasawa d5045c
      p.drawLine(x, 1, x, maxValue);
shun-iwasawa d5045c
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void ChannelHistoGraph::showCurrentChannelValue(int val) {
Shinya Kitaoka 120a6e
  m_pickedValue = val;
Shinya Kitaoka 120a6e
  update();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// ChannelHistoGraph
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
shun-iwasawa d5045c
RGBHistoGraph::RGBHistoGraph(int index, QWidget *parent)
shun-iwasawa d5045c
    : ChannelHistoGraph(index, parent) {
Shinya Kitaoka 120a6e
  m_histoImg = QImage(COMBOHIST_RESOLUTION_W, COMBOHIST_RESOLUTION_H,
Shinya Kitaoka 120a6e
                      QImage::Format_ARGB32_Premultiplied);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
RGBHistoGraph::~RGBHistoGraph() {
Shinya Kitaoka 120a6e
  for (int i = 0; i < 3; i++) m_rgbValues[i].clear();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
shun-iwasawa d5045c
void RGBHistoGraph::setValues(int *buf, bool) {
Shinya Kitaoka 120a6e
  for (int chan = 0; chan < 3; chan++) {
Shinya Kitaoka 120a6e
    m_rgbValues[chan].clear();
Shinya Kitaoka 120a6e
    m_rgbValues[chan].resize(COMBOHIST_RESOLUTION_W);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    int i;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // normalize with the maximum value
Shinya Kitaoka 120a6e
    int maxValue = 1;
Shinya Kitaoka 120a6e
    for (i = 0; i < COMBOHIST_RESOLUTION_W; i++) {
shun-iwasawa d5045c
      int count = buf[COMBOHIST_RESOLUTION_W * chan + i];
Shinya Kitaoka 120a6e
      if (maxValue < count) maxValue = count;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    for (i = 0; i < COMBOHIST_RESOLUTION_W; i++) {
shun-iwasawa d5045c
      int v = buf[COMBOHIST_RESOLUTION_W * chan + i];
Shinya Kitaoka 120a6e
      m_rgbValues[chan][i] =
Shinya Kitaoka 120a6e
          tround((double)(v * COMBOHIST_RESOLUTION_H) / (double)maxValue);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  QPainter imgPainter(&m_histoImg);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  imgPainter.fillRect(m_histoImg.rect(), Qt::black);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (m_rgbValues[0].size() == 0 || m_rgbValues[1].size() == 0 ||
Shinya Kitaoka 120a6e
      m_rgbValues[2].size() == 0) {
Shinya Kitaoka 120a6e
    imgPainter.end();
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  imgPainter.setCompositionMode(QPainter::CompositionMode_Plus);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (int chan = 0; chan < 3; chan++) {
shun-iwasawa 2cda63
    imgPainter.setPen((chan == 0)   ? Qt::red
shun-iwasawa 2cda63
                      : (chan == 1) ? Qt::green
shun-iwasawa 2cda63
                                    : Qt::blue);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    for (int i = 0; i < COMBOHIST_RESOLUTION_W; i++) {
Shinya Kitaoka 120a6e
      int v = m_rgbValues[chan][i];
Shinya Kitaoka 120a6e
      if (v <= 0) continue;
Shinya Kitaoka 120a6e
      int x = 1 + i;
Shinya Kitaoka 120a6e
      imgPainter.drawLine(x, COMBOHIST_RESOLUTION_H + 1 - v, x,
Shinya Kitaoka 120a6e
                          COMBOHIST_RESOLUTION_H);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  imgPainter.setCompositionMode(QPainter::CompositionMode_SourceOver);
Shinya Kitaoka 120a6e
  imgPainter.end();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void RGBHistoGraph::paintEvent(QPaintEvent *event) {
Shinya Kitaoka 120a6e
  QPainter p(this);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  p.setCompositionMode(QPainter::CompositionMode_SourceOver);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  p.setPen(QColor(144, 144, 144));
Shinya Kitaoka 120a6e
  p.setBrush(QColor(64, 64, 64));
Shinya Kitaoka 120a6e
  p.drawRect(rect().x(), rect().y(), rect().width() - 1, rect().height() - 1);
Shinya Kitaoka 120a6e
  p.setBrush(Qt::NoBrush);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  p.drawImage(1, 1, m_histoImg);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// ChannelColorBar
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
ChannelColorBar::ChannelColorBar(QWidget *parent, QColor color)
Shinya Kitaoka 120a6e
    : QWidget(parent), m_color(color) {
Shinya Kitaoka 120a6e
  // 2 pixels margin for width
Shinya Kitaoka 120a6e
  setFixedSize(COMBOHIST_RESOLUTION_W + 2, 6);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void ChannelColorBar::paintEvent(QPaintEvent *event) {
Shinya Kitaoka 120a6e
  QPainter p(this);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  QLinearGradient linearGrad(QPoint(1, 0), QPoint(COMBOHIST_RESOLUTION_W, 0));
Shinya Kitaoka 120a6e
  if (m_color == QColor(0, 0, 0, 0)) {
Shinya Kitaoka 120a6e
    linearGrad.setColorAt(0, m_color);
Shinya Kitaoka 120a6e
    linearGrad.setColorAt(1, Qt::white);
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    linearGrad.setColorAt(0, Qt::black);
shun-iwasawa 481b59
    if (!areAlmostEqual(m_range, 1.))
shun-iwasawa 481b59
      linearGrad.setColorAt(1. / m_range, m_color);
Shinya Kitaoka 120a6e
    linearGrad.setColorAt(1, m_color);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  p.setBrush(QBrush(linearGrad));
Shinya Kitaoka 120a6e
  p.setPen(Qt::NoPen);
Shinya Kitaoka 120a6e
  p.drawRect(rect());
shun-iwasawa 481b59
shun-iwasawa 481b59
  if (!areAlmostEqual(m_range, 1.)) {
shun-iwasawa 481b59
    static const QPointF points[3] = {QPointF(0.0, 0.0), QPointF(3.0, 6.0),
shun-iwasawa 481b59
                                      QPointF(-3.0, 6.0)};
shun-iwasawa 481b59
shun-iwasawa 481b59
    p.setPen(Qt::NoPen);
shun-iwasawa 481b59
    p.setBrush(Qt::black);
shun-iwasawa 481b59
    p.translate(COMBOHIST_RESOLUTION_W / m_range + 1, 0.);
shun-iwasawa 481b59
    p.drawPolygon(points, 3);
shun-iwasawa 481b59
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// ChannelHisto
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
shun-iwasawa d5045c
ChannelHisto::ChannelHisto(int channelIndex, bool *showComparePtr,
Shinya Kitaoka 120a6e
                           QWidget *parent) {
Shinya Kitaoka 120a6e
  QString label;
Shinya Kitaoka 120a6e
  QColor color;
Shinya Kitaoka 120a6e
  switch (channelIndex) {
Shinya Kitaoka 120a6e
  case 0:
Shinya Kitaoka 120a6e
    label = tr("Red");
Shinya Kitaoka 120a6e
    color = Qt::red;
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  case 1:
Shinya Kitaoka 120a6e
    label = tr("Green");
Shinya Kitaoka 120a6e
    color = Qt::green;
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  case 2:
Shinya Kitaoka 120a6e
    label = tr("Blue");
Shinya Kitaoka 120a6e
    color = Qt::blue;
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  case 3:
Shinya Kitaoka 120a6e
    label = tr("Alpha");
Shinya Kitaoka 120a6e
    color = QColor(0, 0, 0, 0);
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  case 4:
shun-iwasawa d5045c
    label = tr("RGB");
Shinya Kitaoka 120a6e
    color = Qt::white;
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (channelIndex != 4)
shun-iwasawa d5045c
    m_histogramGraph =
shun-iwasawa d5045c
        new ChannelHistoGraph(channelIndex, this, showComparePtr);
Shinya Kitaoka 120a6e
  else
shun-iwasawa d5045c
    m_histogramGraph = new RGBHistoGraph(channelIndex, this);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_colorBar = new ChannelColorBar(this, color);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // show/hide the alpha channel
Shinya Kitaoka 120a6e
  QPushButton *showAlphaChannelButton = 0;
Shinya Kitaoka 120a6e
  if (channelIndex == 3) {
Shinya Kitaoka 120a6e
    showAlphaChannelButton = new QPushButton("", this);
Kite 521c84
    showAlphaChannelButton->setObjectName("menuToggleButton");
Shinya Kitaoka 120a6e
    showAlphaChannelButton->setFixedSize(15, 15);
Kite 521c84
    showAlphaChannelButton->setIcon(createQIcon("menu_toggle"));
Shinya Kitaoka 120a6e
    showAlphaChannelButton->setCheckable(true);
Shinya Kitaoka 120a6e
    showAlphaChannelButton->setChecked(false);
Shinya Kitaoka 120a6e
    showAlphaChannelButton->setFocusPolicy(Qt::NoFocus);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // layout
Shinya Kitaoka 120a6e
  QVBoxLayout *mainLayout = new QVBoxLayout(this);
Shinya Kitaoka 120a6e
  mainLayout->setMargin(0);
Shinya Kitaoka 120a6e
  mainLayout->setSpacing(2);
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    QHBoxLayout *titleLay = new QHBoxLayout();
Shinya Kitaoka 120a6e
    titleLay->setMargin(0);
Shinya Kitaoka 120a6e
    titleLay->setSpacing(2);
Shinya Kitaoka 120a6e
    {
Shinya Kitaoka 120a6e
      titleLay->addWidget(new QLabel(label, this), 0);
Shinya Kitaoka 120a6e
      if (channelIndex == 3) titleLay->addWidget(showAlphaChannelButton, 0);
Shinya Kitaoka 120a6e
      titleLay->addStretch(1);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    mainLayout->addLayout(titleLay);
Shinya Kitaoka 120a6e
    mainLayout->addSpacing(3);
Shinya Kitaoka 120a6e
    mainLayout->addWidget(m_histogramGraph);
Shinya Kitaoka 120a6e
    mainLayout->addWidget(m_colorBar);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  setLayout(mainLayout);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (channelIndex == 3) {
Shinya Kitaoka 120a6e
    connect(showAlphaChannelButton, SIGNAL(toggled(bool)), this,
Shinya Kitaoka 120a6e
            SLOT(onShowAlphaButtonToggled(bool)));
Shinya Kitaoka 120a6e
    onShowAlphaButtonToggled(false);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
/*! update the picked color's channel value
shun-iwasawa 21c135
 */
Shinya Kitaoka 120a6e
void ChannelHisto::showCurrentChannelValue(int val) {
Shinya Kitaoka 120a6e
  m_histogramGraph->showCurrentChannelValue(val);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void ChannelHisto::onShowAlphaButtonToggled(bool visible) {
Shinya Kitaoka 120a6e
  m_histogramGraph->setVisible(visible);
Shinya Kitaoka 120a6e
  m_colorBar->setVisible(visible);
shun-iwasawa 2cda63
  emit showButtonToggled(visible);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// ComboHistoRGBLabel
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
ComboHistoRGBLabel::ComboHistoRGBLabel(QColor color, QWidget *parent)
shun-iwasawa 2cda63
    : QWidget(parent)
shun-iwasawa 2cda63
    , m_color(color)
shun-iwasawa 2cda63
    , m_mode(DisplayMode::Display_8bit)
shun-iwasawa 2cda63
    , m_alphaVisible(false) {
shun-iwasawa 2cda63
  setFixedSize(COMBOHIST_RESOLUTION_W, 35);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void ComboHistoRGBLabel::setColorAndUpdate(QColor color) {
Shinya Kitaoka 120a6e
  if (m_color == color) return;
Shinya Kitaoka 120a6e
  m_color = color;
Shinya Kitaoka 120a6e
  update();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void ComboHistoRGBLabel::paintEvent(QPaintEvent *pe) {
Shinya Kitaoka 120a6e
  QPainter p(this);
Shinya Kitaoka 120a6e
  p.setPen(Qt::black);
Shinya Kitaoka 120a6e
  QRect bgRect = QRect(rect().left(), rect().top(), rect().width() - 1,
Shinya Kitaoka 120a6e
                       rect().height() - 1);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (m_color.alpha() == 0) {
Shinya Kitaoka 120a6e
    p.setBrush(Qt::gray);
Shinya Kitaoka 120a6e
    p.drawRect(bgRect);
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
shun-iwasawa 388550
  if (LutManager::instance()->isValid()) {
shun-iwasawa ad7711
    QColor convertedColor(m_color);
shun-iwasawa 388550
    LutManager::instance()->convert(convertedColor);
shun-iwasawa ad7711
    p.setBrush(convertedColor);
shun-iwasawa ad7711
  } else
shun-iwasawa ad7711
    p.setBrush(m_color);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  p.drawRect(bgRect);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // white text for dark color, black text for light color
Shinya Kitaoka 120a6e
  int val = m_color.red() * 30 + m_color.green() * 59 + m_color.blue() * 11;
Shinya Kitaoka 120a6e
  if (val < 12800)
Shinya Kitaoka 120a6e
    p.setPen(Qt::white);
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    p.setPen(Qt::black);
Shinya Kitaoka 120a6e
  p.setBrush(Qt::NoBrush);
Shinya Kitaoka 120a6e
shun-iwasawa d5045c
  QFont font              = p.font();
shun-iwasawa d5045c
  const int pixelSizes[3] = {18, 14, 14};
shun-iwasawa d5045c
  font.setPixelSize(pixelSizes[(int)m_mode]);
shun-iwasawa d5045c
  p.setFont(font);
shun-iwasawa d5045c
  QString colorStr;
shun-iwasawa 2cda63
  QString colorStr2 = QString();
shun-iwasawa d5045c
  switch (m_mode) {
shun-iwasawa d5045c
  case Display_8bit: {
shun-iwasawa d5045c
    colorStr = tr("R:%1 G:%2 B:%3")
shun-iwasawa d5045c
                   .arg(m_color.red())
shun-iwasawa d5045c
                   .arg(m_color.green())
shun-iwasawa d5045c
                   .arg(m_color.blue());
shun-iwasawa 2cda63
    if (m_alphaVisible) colorStr += tr(" A:%1").arg(m_color.alpha());
shun-iwasawa d5045c
    break;
shun-iwasawa d5045c
  }
shun-iwasawa d5045c
  case Display_16bit: {
shun-iwasawa d5045c
    QRgba64 rgba64 = m_color.rgba64();
shun-iwasawa d5045c
    colorStr       = tr("R:%1 G:%2 B:%3")
shun-iwasawa d5045c
                   .arg(rgba64.red())
shun-iwasawa d5045c
                   .arg(rgba64.green())
shun-iwasawa d5045c
                   .arg(rgba64.blue());
shun-iwasawa 2cda63
    if (m_alphaVisible) colorStr += tr(" A:%1").arg(rgba64.alpha());
shun-iwasawa d5045c
    break;
shun-iwasawa d5045c
  }
shun-iwasawa d5045c
  case Display_0_1: {
shun-iwasawa 2cda63
    if (!m_alphaVisible) {
shun-iwasawa 2cda63
      colorStr = tr("R:%1 G:%2 B:%3")
shun-iwasawa 2cda63
                     .arg(m_color.redF())
shun-iwasawa 2cda63
                     .arg(m_color.greenF())
shun-iwasawa 2cda63
                     .arg(m_color.blueF());
shun-iwasawa 2cda63
    } else {
shun-iwasawa 2cda63
      // display in 2 lines
shun-iwasawa 2cda63
      colorStr = tr("R:%1 G:%2 B:%3")
shun-iwasawa 2cda63
                     .arg(m_color.redF())
shun-iwasawa 2cda63
                     .arg(m_color.greenF())
shun-iwasawa 2cda63
                     .arg(m_color.blueF());
shun-iwasawa 2cda63
      colorStr2 = tr("A:%1").arg(m_color.alphaF());
shun-iwasawa 2cda63
    }
shun-iwasawa d5045c
    break;
shun-iwasawa d5045c
  }
shun-iwasawa d5045c
  }
shun-iwasawa 2cda63
  if (colorStr2.isEmpty())
shun-iwasawa 2cda63
    p.drawText(rect(), Qt::AlignCenter, colorStr);
shun-iwasawa 2cda63
  else {
shun-iwasawa 2cda63
    QRect upRect = rect().adjusted(0, 0, 0, -rect().height() / 2);
shun-iwasawa 2cda63
    p.drawText(upRect, Qt::AlignCenter, colorStr);
shun-iwasawa 2cda63
    QRect dnRect = upRect.translated(0, rect().height() / 2);
shun-iwasawa 2cda63
    p.drawText(dnRect, Qt::AlignCenter, colorStr2);
shun-iwasawa 2cda63
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// ComboHistogram
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
ComboHistogram::ComboHistogram(QWidget *parent)
shun-iwasawa d5045c
    : QWidget(parent)
shun-iwasawa d5045c
    , m_raster(0)
shun-iwasawa d5045c
    , m_palette(0)
shun-iwasawa d5045c
    , m_showCompare(false)
shun-iwasawa 481b59
    , m_compHistoIsValid(true)
shun-iwasawa 481b59
    , m_rangeStep(0) {
shun-iwasawa d5045c
  for (int chan = 0; chan < 4; chan++)
shun-iwasawa d5045c
    m_histograms[chan] = new ChannelHisto(chan, &m_showCompare, this);
shun-iwasawa d5045c
  m_histograms[4] = new ChannelHisto(4, &m_showCompare, this);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // RGB label
Shinya Kitaoka 120a6e
  m_rgbLabel = new ComboHistoRGBLabel(QColor(128, 128, 128), this);
shun-iwasawa d5045c
  // m_rgbLabel->setStyleSheet("font-size: 18px;");
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_rectAverageRgbLabel = new ComboHistoRGBLabel(QColor(128, 128, 128), this);
shun-iwasawa d5045c
  // m_rectAverageRgbLabel->setStyleSheet("font-size: 18px;");
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_xPosLabel = new QLabel("", this);
Shinya Kitaoka 120a6e
  m_yPosLabel = new QLabel("", this);
Shinya Kitaoka 120a6e
shun-iwasawa d5045c
  m_displayModeCombo = new QComboBox(this);
shun-iwasawa d5045c
shun-iwasawa 481b59
  m_rangeControlContainer = new QWidget(this);
shun-iwasawa 481b59
  m_rangeUpBtn            = new QPushButton("", this);
shun-iwasawa 481b59
  m_rangeDwnBtn           = new QPushButton("", this);
shun-iwasawa 481b59
  m_rangeLabel            = new QLabel("1.0", this);
shun-iwasawa 481b59
shun-iwasawa 481b59
  //-----
shun-iwasawa 481b59
shun-iwasawa d5045c
  m_displayModeCombo->addItem(
shun-iwasawa d5045c
      tr("8bit (0-255)"), (int)ComboHistoRGBLabel::DisplayMode::Display_8bit);
shun-iwasawa d5045c
  m_displayModeCombo->addItem(
shun-iwasawa d5045c
      tr("16bit (0-65535)"),
shun-iwasawa d5045c
      (int)ComboHistoRGBLabel::DisplayMode::Display_16bit);
shun-iwasawa d5045c
  m_displayModeCombo->addItem(
shun-iwasawa d5045c
      tr("0.0-1.0"), (int)ComboHistoRGBLabel::DisplayMode::Display_0_1);
shun-iwasawa d5045c
shun-iwasawa 481b59
  m_rangeUpBtn->setIcon(createQIcon("prevkey"));
shun-iwasawa 481b59
  m_rangeDwnBtn->setIcon(createQIcon("nextkey"));
shun-iwasawa 481b59
  m_rangeUpBtn->setFixedWidth(17);
shun-iwasawa 481b59
  m_rangeDwnBtn->setFixedWidth(17);
shun-iwasawa 481b59
  m_rangeDwnBtn->setEnabled(false);
shun-iwasawa 481b59
  m_rangeLabel->setFixedWidth(30);
shun-iwasawa 481b59
  m_rangeLabel->setAlignment(Qt::AlignCenter);
shun-iwasawa 481b59
Shinya Kitaoka 120a6e
  // layout
Shinya Kitaoka 120a6e
  QVBoxLayout *mainLayout = new QVBoxLayout();
Shinya Kitaoka 120a6e
  mainLayout->setMargin(5);
Shinya Kitaoka 120a6e
  mainLayout->setSpacing(5);
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    mainLayout->addWidget(m_histograms[4]);  // RGB
Shinya Kitaoka 120a6e
shun-iwasawa d5045c
    QHBoxLayout *labelLay = new QHBoxLayout();
shun-iwasawa d5045c
    labelLay->setMargin(0);
shun-iwasawa d5045c
    labelLay->setSpacing(0);
shun-iwasawa d5045c
    {
shun-iwasawa d5045c
      labelLay->addWidget(new QLabel(tr("Picked Color"), this), 0);
shun-iwasawa d5045c
      labelLay->addStretch(1);
shun-iwasawa d5045c
      labelLay->addWidget(m_displayModeCombo, 0);
shun-iwasawa d5045c
    }
shun-iwasawa d5045c
    mainLayout->addLayout(labelLay, 0);
shun-iwasawa d5045c
Shinya Kitaoka 120a6e
    mainLayout->addWidget(m_rgbLabel, 0, Qt::AlignCenter);
Shinya Kitaoka 120a6e
shun-iwasawa e87e08
    mainLayout->addWidget(new QLabel(tr("Average Color (Ctrl + Drag)"), this),
shun-iwasawa e87e08
                          0, Qt::AlignLeft | Qt::AlignVCenter);
Shinya Kitaoka 120a6e
    mainLayout->addWidget(m_rectAverageRgbLabel, 0, Qt::AlignCenter);
Shinya Kitaoka 120a6e
shun-iwasawa 2cda63
    QHBoxLayout *infoParamLay = new QHBoxLayout();
shun-iwasawa 2cda63
    infoParamLay->setMargin(5);
shun-iwasawa 2cda63
    infoParamLay->setSpacing(3);
Shinya Kitaoka 120a6e
    {
shun-iwasawa 2cda63
      infoParamLay->addWidget(new QLabel(tr("X:"), this), 1,
Shinya Kitaoka 120a6e
                              Qt::AlignRight | Qt::AlignVCenter);
shun-iwasawa 2cda63
      infoParamLay->addWidget(m_xPosLabel, 1, Qt::AlignLeft | Qt::AlignVCenter);
shun-iwasawa 2cda63
      infoParamLay->addWidget(new QLabel(tr("Y:"), this), 1,
Shinya Kitaoka 120a6e
                              Qt::AlignRight | Qt::AlignVCenter);
shun-iwasawa 2cda63
      infoParamLay->addWidget(m_yPosLabel, 2, Qt::AlignLeft | Qt::AlignVCenter);
shun-iwasawa 481b59
shun-iwasawa 481b59
      // range control
shun-iwasawa 481b59
      QHBoxLayout *rangeLay = new QHBoxLayout();
shun-iwasawa 481b59
      rangeLay->setMargin(0);
shun-iwasawa 481b59
      rangeLay->setSpacing(0);
shun-iwasawa 481b59
      {
shun-iwasawa 481b59
        rangeLay->addWidget(m_rangeUpBtn, 0);
shun-iwasawa 481b59
        rangeLay->addWidget(m_rangeLabel, 0);
shun-iwasawa 481b59
        rangeLay->addWidget(m_rangeDwnBtn, 0);
shun-iwasawa 481b59
      }
shun-iwasawa 481b59
      m_rangeControlContainer->setLayout(rangeLay);
shun-iwasawa 481b59
      infoParamLay->addWidget(m_rangeControlContainer, 0);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    mainLayout->addLayout(infoParamLay, 0);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    mainLayout->addWidget(m_histograms[0]);  // R
Shinya Kitaoka 120a6e
    mainLayout->addWidget(m_histograms[1]);  // G
Shinya Kitaoka 120a6e
    mainLayout->addWidget(m_histograms[2]);  // B
Shinya Kitaoka 120a6e
    mainLayout->addWidget(m_histograms[3]);  // A
Shinya Kitaoka 120a6e
    mainLayout->addStretch(1);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  setLayout(mainLayout);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_rectAverageRgbLabel->setColorAndUpdate(Qt::transparent);
shun-iwasawa d5045c
shun-iwasawa d5045c
  connect(m_displayModeCombo, SIGNAL(activated(int)), this,
shun-iwasawa d5045c
          SLOT(onDisplayModeChanged()));
shun-iwasawa 2cda63
  connect(m_histograms[3], SIGNAL(showButtonToggled(bool)), this,
shun-iwasawa 2cda63
          SLOT(onShowAlphaButtonToggled(bool)));
shun-iwasawa 481b59
  connect(m_rangeUpBtn, SIGNAL(clicked()), this, SLOT(onRangeUp()));
shun-iwasawa 481b59
  connect(m_rangeDwnBtn, SIGNAL(clicked()), this, SLOT(onRangeDown()));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
ComboHistogram::~ComboHistogram() {
Shinya Kitaoka 120a6e
  memset(m_channelValue, 0, sizeof m_channelValue);
shun-iwasawa d5045c
  memset(m_channelValueComp, 0, sizeof m_channelValueComp);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void ComboHistogram::setRaster(const TRasterP &raster,
Shinya Kitaoka 120a6e
                               const TPaletteP &palette) {
Shinya Kitaoka 120a6e
  if (palette.getPointer()) m_palette = palette;
shun-iwasawa d5045c
  m_raster = raster;
shun-iwasawa 481b59
shun-iwasawa 481b59
  refreshHistogram();
shun-iwasawa 481b59
shun-iwasawa 481b59
  m_rangeControlContainer->setVisible(!!((TRasterFP)raster));
shun-iwasawa 481b59
  update();
shun-iwasawa 481b59
}
shun-iwasawa 481b59
shun-iwasawa 481b59
//-----------------------------------------------------------------------------
shun-iwasawa 481b59
shun-iwasawa 481b59
void ComboHistogram::refreshHistogram() {
shun-iwasawa d5045c
  computeChannelsValue(&m_channelValue[0][0], sizeof(m_channelValue), m_raster);
Toshihiro Shimizu 890ddd
shun-iwasawa 481b59
  float range = 1.f;
shun-iwasawa 481b59
  if (!!((TRasterFP)m_raster)) {
shun-iwasawa 481b59
    range = std::pow(2.f, (float)m_rangeStep);
shun-iwasawa 481b59
  }
shun-iwasawa 481b59
shun-iwasawa 481b59
  for (int chan = 0; chan < 4; chan++) {
shun-iwasawa d5045c
    m_histograms[chan]->refleshValue(&m_channelValue[chan][0]);
shun-iwasawa 481b59
    if (chan != 3)  // rgb channels
shun-iwasawa 481b59
      m_histograms[chan]->setRange(range);
shun-iwasawa 481b59
  }
shun-iwasawa d5045c
  m_histograms[4]->refleshValue(&m_channelValue[0][0]);
shun-iwasawa 481b59
  m_histograms[4]->setRange(range);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
shun-iwasawa d5045c
void ComboHistogram::computeChannelsValue(int *buf, size_t size, TRasterP ras,
shun-iwasawa d5045c
                                          TPalette *extPlt) {
shun-iwasawa d5045c
  memset(buf, 0, size);
shun-iwasawa d5045c
  if (!ras.getPointer()) return;
shun-iwasawa d5045c
  TRasterCM32P cmRaster = ras;
Shinya Kitaoka 120a6e
  bool isCmRaster       = !!cmRaster;
Shinya Kitaoka 120a6e
shun-iwasawa d5045c
  TRaster64P raster64 = ras;
Shinya Kitaoka 120a6e
  bool is64bit        = !!raster64;
Shinya Kitaoka 120a6e
shun-iwasawa 481b59
  TRasterFP rasF = ras;
shun-iwasawa 481b59
shun-iwasawa 481b59
  float factor = 1.f / std::pow(2.f, (float)m_rangeStep);
shun-iwasawa 481b59
shun-iwasawa d5045c
  int lx = ras->getLx();
shun-iwasawa d5045c
  int ly = ras->getLy();
Shinya Kitaoka 120a6e
  if (lx > 1 && ly > 1) {
Shinya Kitaoka 120a6e
    int i, j;
Shinya Kitaoka 120a6e
    if (is64bit) {
Shinya Kitaoka 120a6e
      for (j = 0; j < ly; j++) {
Shinya Kitaoka 120a6e
        TPixel64 *pix_64 = raster64->pixels(j);
Shinya Kitaoka 120a6e
        for (i = 0; i < lx; i++, pix_64++) {
Shinya Kitaoka 120a6e
          int mValue = (int)byteFromUshort(pix_64->m);
Shinya Kitaoka 120a6e
          if (mValue != 0) {
shun-iwasawa d5045c
            ++buf[idx(0, (int)byteFromUshort(pix_64->r))];
shun-iwasawa d5045c
            ++buf[idx(1, (int)byteFromUshort(pix_64->g))];
shun-iwasawa d5045c
            ++buf[idx(2, (int)byteFromUshort(pix_64->b))];
Shinya Kitaoka 120a6e
          }
shun-iwasawa d5045c
          ++buf[idx(3, mValue)];
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    } else if (isCmRaster) {
shun-iwasawa d5045c
      TPalette *plt = (extPlt) ? extPlt : m_palette.getPointer();
shun-iwasawa d5045c
      assert(plt);
Shinya Kitaoka 120a6e
      for (j = 0; j < ly; j++) {
Shinya Kitaoka 120a6e
        TPixelCM32 *pix_cm = cmRaster->pixels(j);
Shinya Kitaoka 120a6e
        for (i = 0; i < lx; i++, pix_cm++) {
Shinya Kitaoka 120a6e
          int styleId =
Shinya Kitaoka 120a6e
              pix_cm->getTone() < 127 ? pix_cm->getInk() : pix_cm->getPaint();
shun-iwasawa d5045c
          TColorStyle *colorStyle = plt->getStyle(styleId);
Shinya Kitaoka 120a6e
          if (!colorStyle) continue;
Shinya Kitaoka 120a6e
          TPixel color = colorStyle->getAverageColor();
Shinya Kitaoka 120a6e
          int mValue   = color.m;
Shinya Kitaoka 120a6e
          if (mValue != 0) {
shun-iwasawa d5045c
            ++buf[idx(0, color.r)];
shun-iwasawa d5045c
            ++buf[idx(1, color.g)];
shun-iwasawa d5045c
            ++buf[idx(2, color.b)];
Shinya Kitaoka 120a6e
          }
shun-iwasawa d5045c
          ++buf[idx(3, color.m)];
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
shun-iwasawa 481b59
    } else if (rasF) {
shun-iwasawa 481b59
      for (j = 0; j < ly; j++) {
shun-iwasawa 481b59
        TPixelF *pixF = rasF->pixels(j);
shun-iwasawa 481b59
        for (i = 0; i < lx; i++, pixF++) {
shun-iwasawa 481b59
          int mValue = (int)byteFromFloat(pixF->m);
shun-iwasawa 481b59
          if (mValue != 0) {
shun-iwasawa 481b59
            ++buf[idx(0, (int)byteFromFloat(pixF->r * factor))];
shun-iwasawa 481b59
            ++buf[idx(1, (int)byteFromFloat(pixF->g * factor))];
shun-iwasawa 481b59
            ++buf[idx(2, (int)byteFromFloat(pixF->b * factor))];
shun-iwasawa 481b59
          }
shun-iwasawa 481b59
          ++buf[idx(3, mValue)];
shun-iwasawa 481b59
        }
shun-iwasawa 481b59
      }
Shinya Kitaoka 120a6e
    } else  // 8bpc raster
Shinya Kitaoka 120a6e
    {
Shinya Kitaoka 120a6e
      for (j = 0; j < ly; j++) {
shun-iwasawa d5045c
        TPixel *pix = (TPixel *)ras->getRawData(0, j);
Shinya Kitaoka 120a6e
        for (i = 0; i < lx; i++, pix++) {
Shinya Kitaoka 120a6e
          int mValue = pix->m;
Shinya Kitaoka 120a6e
          if (mValue != 0) {
shun-iwasawa d5045c
            ++buf[idx(0, pix->r)];
shun-iwasawa d5045c
            ++buf[idx(1, pix->g)];
shun-iwasawa d5045c
            ++buf[idx(2, pix->b)];
Shinya Kitaoka 120a6e
          }
shun-iwasawa d5045c
          ++buf[idx(3, pix->m)];
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void ComboHistogram::updateInfo(const TPixel32 &pix, const TPointD &imagePos) {
Shinya Kitaoka 120a6e
  if (pix == TPixel32::Transparent) {
Shinya Kitaoka 120a6e
    m_histograms[0]->showCurrentChannelValue(-1);
Shinya Kitaoka 120a6e
    m_histograms[1]->showCurrentChannelValue(-1);
Shinya Kitaoka 120a6e
    m_histograms[2]->showCurrentChannelValue(-1);
shun-iwasawa 2cda63
    m_histograms[3]->showCurrentChannelValue(-1);
Shinya Kitaoka 120a6e
    m_rgbLabel->setColorAndUpdate(Qt::transparent);
Shinya Kitaoka 120a6e
    m_xPosLabel->setText("");
Shinya Kitaoka 120a6e
    m_yPosLabel->setText("");
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    // show picked color's channel values
Shinya Kitaoka 120a6e
    m_histograms[0]->showCurrentChannelValue((int)pix.r);
Shinya Kitaoka 120a6e
    m_histograms[1]->showCurrentChannelValue((int)pix.g);
Shinya Kitaoka 120a6e
    m_histograms[2]->showCurrentChannelValue((int)pix.b);
shun-iwasawa 2cda63
    m_histograms[3]->showCurrentChannelValue((int)pix.m);
shun-iwasawa 2cda63
    m_rgbLabel->setColorAndUpdate(
shun-iwasawa 2cda63
        QColor((int)pix.r, (int)pix.g, (int)pix.b, (int)pix.m));
Shinya Kitaoka 120a6e
    m_xPosLabel->setText(QString::number(tround(imagePos.x)));
Shinya Kitaoka 120a6e
    m_yPosLabel->setText(QString::number(tround(imagePos.y)));
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
shun-iwasawa d5045c
void ComboHistogram::updateInfo(const TPixel64 &pix, const TPointD &imagePos) {
shun-iwasawa d5045c
  if (pix == TPixel64::Transparent) {
shun-iwasawa d5045c
    m_histograms[0]->showCurrentChannelValue(-1);
shun-iwasawa d5045c
    m_histograms[1]->showCurrentChannelValue(-1);
shun-iwasawa d5045c
    m_histograms[2]->showCurrentChannelValue(-1);
shun-iwasawa 2cda63
    m_histograms[3]->showCurrentChannelValue(-1);
shun-iwasawa d5045c
    m_rgbLabel->setColorAndUpdate(Qt::transparent);
shun-iwasawa d5045c
    m_xPosLabel->setText("");
shun-iwasawa d5045c
    m_yPosLabel->setText("");
shun-iwasawa d5045c
  } else {
shun-iwasawa d5045c
    TPixel32 pix32 = toPixel32(pix);
shun-iwasawa d5045c
    // show picked color's channel values
shun-iwasawa d5045c
    m_histograms[0]->showCurrentChannelValue((int)pix32.r);
shun-iwasawa d5045c
    m_histograms[1]->showCurrentChannelValue((int)pix32.g);
shun-iwasawa d5045c
    m_histograms[2]->showCurrentChannelValue((int)pix32.b);
shun-iwasawa 2cda63
    m_histograms[3]->showCurrentChannelValue((int)pix32.m);
shun-iwasawa 2cda63
    m_rgbLabel->setColorAndUpdate(QColor::fromRgba64(
shun-iwasawa 2cda63
        (ushort)pix.r, (ushort)pix.g, (ushort)pix.b, (ushort)pix.m));
shun-iwasawa d5045c
    m_xPosLabel->setText(QString::number(tround(imagePos.x)));
shun-iwasawa d5045c
    m_yPosLabel->setText(QString::number(tround(imagePos.y)));
shun-iwasawa d5045c
  }
shun-iwasawa d5045c
}
shun-iwasawa d5045c
shun-iwasawa d5045c
//-----------------------------------------------------------------------------
shun-iwasawa d5045c
shun-iwasawa 481b59
void ComboHistogram::updateInfo(const TPixelF &pix, const TPointD &imagePos) {
shun-iwasawa 481b59
  if (pix == TPixelF::Transparent) {
shun-iwasawa 481b59
    m_histograms[0]->showCurrentChannelValue(-1);
shun-iwasawa 481b59
    m_histograms[1]->showCurrentChannelValue(-1);
shun-iwasawa 481b59
    m_histograms[2]->showCurrentChannelValue(-1);
shun-iwasawa 481b59
    m_histograms[3]->showCurrentChannelValue(-1);
shun-iwasawa 481b59
    m_rgbLabel->setColorAndUpdate(Qt::transparent);
shun-iwasawa 481b59
    m_xPosLabel->setText("");
shun-iwasawa 481b59
    m_yPosLabel->setText("");
shun-iwasawa 481b59
  } else {
shun-iwasawa 481b59
    float factor   = std::pow(2.f, -(float)m_rangeStep);
shun-iwasawa 481b59
    TPixel32 pix32 = toPixel32(
shun-iwasawa 481b59
        TPixelF(pix.r * factor, pix.g * factor, pix.b * factor, pix.m));
shun-iwasawa 481b59
    // show picked color's channel values
shun-iwasawa 481b59
    m_histograms[0]->showCurrentChannelValue((int)pix32.r);
shun-iwasawa 481b59
    m_histograms[1]->showCurrentChannelValue((int)pix32.g);
shun-iwasawa 481b59
    m_histograms[2]->showCurrentChannelValue((int)pix32.b);
shun-iwasawa 481b59
    m_histograms[3]->showCurrentChannelValue((int)pix32.m);
shun-iwasawa 481b59
    m_rgbLabel->setColorAndUpdate(QColor::fromRgbF(pix.r, pix.g, pix.b, pix.m));
shun-iwasawa 481b59
    m_xPosLabel->setText(QString::number(tround(imagePos.x)));
shun-iwasawa 481b59
    m_yPosLabel->setText(QString::number(tround(imagePos.y)));
shun-iwasawa 481b59
  }
shun-iwasawa 481b59
}
shun-iwasawa 481b59
//-----------------------------------------------------------------------------
shun-iwasawa 481b59
Shinya Kitaoka 120a6e
void ComboHistogram::updateAverageColor(const TPixel32 &pix) {
Shinya Kitaoka 120a6e
  if (pix == TPixel32::Transparent) {
Shinya Kitaoka 120a6e
    m_rectAverageRgbLabel->setColorAndUpdate(Qt::transparent);
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    m_rectAverageRgbLabel->setColorAndUpdate(
shun-iwasawa 2cda63
        QColor((int)pix.r, (int)pix.g, (int)pix.b, (int)pix.m));
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
shun-iwasawa d5045c
shun-iwasawa d5045c
void ComboHistogram::updateAverageColor(const TPixel64 &pix) {
shun-iwasawa d5045c
  if (pix == TPixel64::Transparent) {
shun-iwasawa d5045c
    m_rectAverageRgbLabel->setColorAndUpdate(Qt::transparent);
shun-iwasawa d5045c
  } else {
shun-iwasawa 2cda63
    m_rectAverageRgbLabel->setColorAndUpdate(QColor::fromRgba64(
shun-iwasawa 2cda63
        (ushort)pix.r, (ushort)pix.g, (ushort)pix.b, (ushort)pix.m));
shun-iwasawa d5045c
  }
shun-iwasawa d5045c
}
shun-iwasawa d5045c
shun-iwasawa d5045c
//-----------------------------------------------------------------------------
shun-iwasawa d5045c
shun-iwasawa 481b59
void ComboHistogram::updateAverageColor(const TPixelF &pix) {
shun-iwasawa 481b59
  if (pix == TPixelF::Transparent) {
shun-iwasawa 481b59
    m_rectAverageRgbLabel->setColorAndUpdate(Qt::transparent);
shun-iwasawa 481b59
  } else {
shun-iwasawa 481b59
    m_rectAverageRgbLabel->setColorAndUpdate(
shun-iwasawa 481b59
        QColor::fromRgbF(pix.r, pix.g, pix.b, pix.m));
shun-iwasawa 481b59
  }
shun-iwasawa 481b59
}
shun-iwasawa 481b59
shun-iwasawa 481b59
//-----------------------------------------------------------------------------
shun-iwasawa 481b59
shun-iwasawa d5045c
void ComboHistogram::onDisplayModeChanged() {
shun-iwasawa d5045c
  ComboHistoRGBLabel::DisplayMode mode =
shun-iwasawa d5045c
      static_cast<combohistorgblabel::displaymode>(</combohistorgblabel::displaymode>
shun-iwasawa d5045c
          m_displayModeCombo->currentData().toInt());
shun-iwasawa d5045c
  m_rgbLabel->setDisplayMode(mode);
shun-iwasawa d5045c
  m_rectAverageRgbLabel->setDisplayMode(mode);
shun-iwasawa d5045c
  HistogramChannelDisplayMode = (int)mode;
shun-iwasawa d5045c
  update();
shun-iwasawa d5045c
}
shun-iwasawa d5045c
shun-iwasawa d5045c
//-----------------------------------------------------------------------------
shun-iwasawa d5045c
shun-iwasawa d5045c
void ComboHistogram::updateCompHistogram() {
shun-iwasawa d5045c
  assert(!m_compHistoIsValid);
shun-iwasawa d5045c
  m_compHistoIsValid = true;
shun-iwasawa d5045c
shun-iwasawa d5045c
  TImageP refimg =
shun-iwasawa d5045c
      TImageCache::instance()->get(QString("TnzCompareImg"), false);
shun-iwasawa d5045c
shun-iwasawa d5045c
  if (!(TToonzImageP)refimg && !(TRasterImageP)refimg) return;
shun-iwasawa d5045c
shun-iwasawa d5045c
  computeChannelsValue(&m_channelValueComp[0][0], sizeof m_channelValueComp,
shun-iwasawa d5045c
                       refimg->raster(), refimg->getPalette());
shun-iwasawa d5045c
shun-iwasawa d5045c
  for (int chan = 0; chan < 4; chan++)
shun-iwasawa d5045c
    m_histograms[chan]->refleshValue(&m_channelValueComp[chan][0], true);
shun-iwasawa d5045c
}
shun-iwasawa d5045c
shun-iwasawa d5045c
//-----------------------------------------------------------------------------
shun-iwasawa d5045c
shun-iwasawa d5045c
void ComboHistogram::showEvent(QShowEvent *) {
shun-iwasawa d5045c
  if (!m_compHistoIsValid && m_showCompare) updateCompHistogram();
shun-iwasawa d5045c
shun-iwasawa d5045c
  int envMode = HistogramChannelDisplayMode;
shun-iwasawa d5045c
  m_displayModeCombo->setCurrentIndex(m_displayModeCombo->findData(envMode));
shun-iwasawa d5045c
  ComboHistoRGBLabel::DisplayMode mode =
shun-iwasawa d5045c
      static_cast<combohistorgblabel::displaymode>(envMode);</combohistorgblabel::displaymode>
shun-iwasawa d5045c
  m_rgbLabel->setDisplayMode(mode);
shun-iwasawa d5045c
  m_rectAverageRgbLabel->setDisplayMode(mode);
shun-iwasawa 2cda63
}
shun-iwasawa 2cda63
shun-iwasawa 2cda63
//-----------------------------------------------------------------------------
shun-iwasawa 2cda63
shun-iwasawa 2cda63
void ComboHistogram::onShowAlphaButtonToggled(bool alphaVisible) {
shun-iwasawa 2cda63
  m_rgbLabel->setAlphaVisible(alphaVisible);
shun-iwasawa 2cda63
  m_rectAverageRgbLabel->setAlphaVisible(alphaVisible);
shun-iwasawa 2cda63
  m_rgbLabel->update();
shun-iwasawa 2cda63
  m_rectAverageRgbLabel->update();
shun-iwasawa 481b59
}
shun-iwasawa 481b59
shun-iwasawa 481b59
//-----------------------------------------------------------------------------
shun-iwasawa 481b59
shun-iwasawa 481b59
void ComboHistogram::onRangeUp() {
shun-iwasawa 481b59
  m_rangeStep++;
shun-iwasawa 481b59
  m_rangeDwnBtn->setEnabled(true);
shun-iwasawa 481b59
  if (m_rangeStep == 3) m_rangeUpBtn->setDisabled(true);
shun-iwasawa 481b59
shun-iwasawa 481b59
  m_rangeLabel->setText(QString("%1.0").arg(std::pow(2, m_rangeStep)));
shun-iwasawa 481b59
shun-iwasawa 481b59
  refreshHistogram();
shun-iwasawa 481b59
  m_compHistoIsValid = false;
shun-iwasawa 481b59
  if (m_showCompare) updateCompHistogram();
shun-iwasawa 481b59
shun-iwasawa 481b59
  update();
shun-iwasawa 481b59
}
shun-iwasawa 481b59
shun-iwasawa 481b59
//-----------------------------------------------------------------------------
shun-iwasawa 481b59
shun-iwasawa 481b59
void ComboHistogram::onRangeDown() {
shun-iwasawa 481b59
  m_rangeStep--;
shun-iwasawa 481b59
  m_rangeUpBtn->setEnabled(true);
shun-iwasawa 481b59
  if (m_rangeStep == 0) m_rangeDwnBtn->setDisabled(true);
shun-iwasawa 481b59
shun-iwasawa 481b59
  m_rangeLabel->setText(QString("%1.0").arg(std::pow(2, m_rangeStep)));
shun-iwasawa 481b59
shun-iwasawa 481b59
  refreshHistogram();
shun-iwasawa 481b59
  m_compHistoIsValid = false;
shun-iwasawa 481b59
  if (m_showCompare) updateCompHistogram();
shun-iwasawa 481b59
shun-iwasawa 481b59
  update();
shun-iwasawa d5045c
}