Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "ttest.h"
Toshihiro Shimizu 890ddd
#include "tsystem.h"
Toshihiro Shimizu 890ddd
#include "tfilepath_io.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tlevel_io.h"
Toshihiro Shimizu 890ddd
#include "tfx.h"
Toshihiro Shimizu 890ddd
#include "tparam.h"
Toshihiro Shimizu 890ddd
#include "tpalette.h"
Toshihiro Shimizu 890ddd
#include "ttoonzimage.h"
Toshihiro Shimizu 890ddd
#include "trasterimage.h"
Toshihiro Shimizu 890ddd
#include "tstroke.h"
Toshihiro Shimizu 890ddd
#include "tcolorstyles.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include <set></set>
tomosu eea0ac
#include <sstream></sstream>
Toshihiro Shimizu 890ddd
Campbell Barton 0648b4
#if defined(LINUX)
Campbell Barton 107701
#include <typeinfo></typeinfo>
Campbell Barton 107701
#endif
Campbell Barton 107701
Toshihiro Shimizu 890ddd
using namespace std;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
class TTestTable {
Shinya Kitaoka 120a6e
  typedef map<std::string, *="" ttest=""> Table;</std::string,>
Shinya Kitaoka 120a6e
  typedef set<std::string> SkipTable;</std::string>
Shinya Kitaoka 120a6e
  Table m_table;
Shinya Kitaoka 120a6e
  SkipTable m_skipTable;
Shinya Kitaoka 120a6e
  TTestTable(){};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  static TTestTable *table() {
Shinya Kitaoka 120a6e
    static TTestTable *theTable = 0;
Shinya Kitaoka 120a6e
    if (!theTable) theTable     = new TTestTable;
Shinya Kitaoka 120a6e
    return theTable;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void add(const std::string &str, TTest *test) {
Shinya Kitaoka 120a6e
    assert(test);
Shinya Kitaoka 120a6e
    if (m_table.find(str) != m_table.end()) {
Shinya Kitaoka 120a6e
      cout << "*error* Duplicate test name '" << str << "'" << endl;
Shinya Kitaoka 120a6e
      assert(0);
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    m_table[str] = test;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void skip(const std::string &str) { m_skipTable.insert(str); }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void run(const std::string &str) {
Shinya Kitaoka 120a6e
    if (m_skipTable.find(str) != m_skipTable.end()) return;
Shinya Kitaoka 120a6e
    Table::iterator it = m_table.find(str);
Shinya Kitaoka 120a6e
    if (it == m_table.end())
Shinya Kitaoka 120a6e
      cout << "*error* test '" << str << "' not found" << endl;
Shinya Kitaoka 120a6e
    else {
Shinya Kitaoka 120a6e
      cout << "\nVerifying " << str << " ... " << endl;
Shinya Kitaoka 120a6e
      it->second->before();
Shinya Kitaoka 120a6e
      it->second->test();
Shinya Kitaoka 120a6e
      it->second->after();
Shinya Kitaoka 120a6e
      cout << "OK" << endl;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void runAll() {
Shinya Kitaoka 120a6e
    int count = 0;
Shinya Kitaoka 120a6e
    cout << "Running all tests:" << endl;
Shinya Kitaoka 120a6e
    Table::iterator it;
Shinya Kitaoka 120a6e
    for (it = m_table.begin(); it != m_table.end(); ++it) {
Shinya Kitaoka 120a6e
      run(it->first);
Shinya Kitaoka 120a6e
      ++count;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    cout << count << " test(s) launched" << endl;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void runType(string type) {
Shinya Kitaoka 120a6e
    int count = 0;
Shinya Kitaoka 120a6e
    cout << "Running " << type << " tests:" << endl;
Shinya Kitaoka 120a6e
    Table::iterator it;
Shinya Kitaoka 120a6e
    for (it = m_table.begin(); it != m_table.end(); ++it) {
Shinya Kitaoka 120a6e
      string str(it->first);
Shinya Kitaoka 120a6e
      int i = str.find("_");
Shinya Kitaoka 120a6e
      if (i <= 0) continue;
Shinya Kitaoka 120a6e
      string subStr(str, 0, i);
Shinya Kitaoka 120a6e
      if (subStr == type) run(it->first);
Shinya Kitaoka 120a6e
      ++count;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    cout << count << " test(s) launched" << endl;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TTest::TTest(const std::string &testName) {
Shinya Kitaoka 120a6e
  TTestTable::table()->add(testName, this);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TTest::~TTest() {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TTest::setInstanceCount() {
Shinya Kitaoka 120a6e
  m_levelInstanceCount       = TLevel::getInstanceCount();
Shinya Kitaoka 120a6e
  m_imageInstanceCount       = TImage::getInstanceCount();
Shinya Kitaoka 120a6e
  m_rasterInstanceCount      = TRaster::getInstanceCount();
Shinya Kitaoka 120a6e
  m_imageReaderInstanceCount = TImageReader::getInstanceCount();
Shinya Kitaoka 120a6e
  m_imageWriterInstanceCount = TImageWriter::getInstanceCount();
Shinya Kitaoka 120a6e
  m_levelReaderInstanceCount = TLevelReader::getInstanceCount();
Shinya Kitaoka 120a6e
  m_levelWriterInstanceCount = TLevelWriter::getInstanceCount();
Shinya Kitaoka 120a6e
  m_paramInstanceCount       = TParam::getInstanceCount();
Shinya Kitaoka 120a6e
  m_fxInstanceCount          = TFx::getInstanceCount();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TTest::verifyInstanceCount() {
Shinya Kitaoka 120a6e
  assert(m_levelInstanceCount == TLevel::getInstanceCount());
Shinya Kitaoka 120a6e
  assert(m_imageInstanceCount == TImage::getInstanceCount());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // assert(m_rasterInstanceCount==TRaster::getInstanceCount());
Shinya Kitaoka 120a6e
  // commentata da gmt: in qualche test viene creata un
Shinya Kitaoka 120a6e
  // offline gl context con annesso raster che ovviamente non
Shinya Kitaoka 120a6e
  // viene liberato.
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  assert(m_imageReaderInstanceCount == TImageReader::getInstanceCount());
Shinya Kitaoka 120a6e
  assert(m_imageWriterInstanceCount == TImageWriter::getInstanceCount());
Shinya Kitaoka 120a6e
  assert(m_levelReaderInstanceCount == TLevelReader::getInstanceCount());
Shinya Kitaoka 120a6e
  assert(m_levelWriterInstanceCount == TLevelWriter::getInstanceCount());
Shinya Kitaoka 120a6e
  assert(m_paramInstanceCount == TParam::getInstanceCount());
Shinya Kitaoka 120a6e
  assert(m_fxInstanceCount == TFx::getInstanceCount());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TTest::runTests(string name) {
Shinya Kitaoka 120a6e
  TFilePath testFile = getTestFile(name);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::vector<std::string> testType;</std::string>
Shinya Kitaoka 120a6e
  if (name == "verif_image") {
Shinya Kitaoka 120a6e
    testType.push_back("write");
Shinya Kitaoka 120a6e
    testType.push_back("read");
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  Tifstream is(testFile);
Shinya Kitaoka 120a6e
  if (!is) {
Shinya Kitaoka 120a6e
    cout << "*error* test file '" << testFile << "' not found" << endl;
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  cout << "Test file : '" << testFile << "'" << endl;
Shinya Kitaoka 120a6e
  char buffer[1024];
Shinya Kitaoka 120a6e
  while (is.getline(buffer, sizeof(buffer))) {
Shinya Kitaoka 120a6e
    std::istringstream ss(buffer);
Shinya Kitaoka 120a6e
    while (ss) {
Shinya Kitaoka 120a6e
      string s;
Shinya Kitaoka 120a6e
      ss >> s;
Shinya Kitaoka 120a6e
      if (s == "") continue;
Shinya Kitaoka 120a6e
      if (s[0] == '#' || s[0] == '!') break;
Shinya Kitaoka 120a6e
      // Verifica tutti i test
Shinya Kitaoka 120a6e
      if (s == "all") {
Shinya Kitaoka 120a6e
        TTestTable::table()->runAll();
Shinya Kitaoka 120a6e
        continue;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      // Verifica una parte dei test che ha come nome iniziale testType[i]
Shinya Kitaoka 120a6e
      int i;
Shinya Kitaoka 120a6e
      bool isTypeFound = false;
Shinya Kitaoka 120a6e
      for (i = 0; i < (int)testType.size(); i++)
Shinya Kitaoka 120a6e
        if (s == testType[i]) {
Shinya Kitaoka 120a6e
          isTypeFound = true;
Shinya Kitaoka 120a6e
          TTestTable::table()->runType(testType[i]);
Shinya Kitaoka 120a6e
          break;
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      if (isTypeFound) continue;
Shinya Kitaoka 120a6e
      if (s[0] == '~')
Shinya Kitaoka 120a6e
        TTestTable::table()->skip(s.substr(1));
Shinya Kitaoka 120a6e
      else  // Verifica il test di nome s
Shinya Kitaoka 120a6e
        TTestTable::table()->run(s);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//================================================================================
Toshihiro Shimizu 890ddd
// Utility
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TFilePath getTestFile(string name) {
Shinya Kitaoka 120a6e
  TFilePath testFile;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TFilePath parentDir = TSystem::getBinDir().getParentDir();
Shinya Kitaoka 9f5a1b
#ifndef _WIN32
Shinya Kitaoka 120a6e
  parentDir = parentDir.getParentDir();
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TFilePath relativePath;
Toshihiro Shimizu 890ddd
#ifndef NDEBUG
Shinya Kitaoka 120a6e
  relativePath = parentDir + TFilePath("projects\\test\\") + TFilePath(name);
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
  if (name == "verify_tnzcore")
Shinya Kitaoka 120a6e
    testFile = relativePath + TFilePath(name).withType("txt");
Shinya Kitaoka 120a6e
  else if (name == "verify_toonzlib")
Shinya Kitaoka 120a6e
    testFile = relativePath + TFilePath(name).withType("txt");
Shinya Kitaoka 120a6e
  else if (name == "verify_image")
Shinya Kitaoka 120a6e
    testFile = relativePath + TFilePath(name).withType("txt");
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    testFile = parentDir + TFilePath(name).withType("txt");
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return testFile;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*!
Toshihiro Shimizu 890ddd
*  Return true if \b ra raster and \b rb raster are equal, with an error
Toshihiro Shimizu 890ddd
*  less than \b err; return false otherwise.
Toshihiro Shimizu 890ddd
*  To verify rasters parity check pixel raster; if rasters are different is
Toshihiro Shimizu 890ddd
*	 showed an error message.
Toshihiro Shimizu 890ddd
*
Toshihiro Shimizu 890ddd
*  \b err max variance allowed to value pixels.
Toshihiro Shimizu 890ddd
*
Toshihiro Shimizu 890ddd
*  OSS.: Usually \b ra is check image and \b rb reference image.
Toshihiro Shimizu 890ddd
*/
Shinya Kitaoka 120a6e
int areEqual(TRasterP ra, TRasterP rb, double err) {
Shinya Kitaoka 120a6e
  if (!ra && !rb) return true;
Shinya Kitaoka 120a6e
  int y, x;
Shinya Kitaoka 120a6e
  if (typeid(ra) != typeid(rb)) return false;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!ra || !rb) return false;
Shinya Kitaoka 120a6e
  if (ra->getSize() != rb->getSize()) return false;
Shinya Kitaoka 120a6e
  const int rowSize = ra->getRowSize();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TRaster32P ra32     = ra;
Shinya Kitaoka 120a6e
  TRaster64P ra64     = ra;
Shinya Kitaoka 120a6e
  TRasterGR8P raGR8   = ra;
Shinya Kitaoka 120a6e
  TRasterCM32P raCM32 = ra;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (ra32) {
Shinya Kitaoka 120a6e
    TRaster32P rb32 = rb;
Shinya Kitaoka 120a6e
    if (!rb32) return 2;
Shinya Kitaoka 120a6e
    for (y = 0; y < ra->getLy(); y++)
Shinya Kitaoka 120a6e
      for (x = 0; x < ra->getLx(); x++) {
Shinya Kitaoka 120a6e
        TPixel32 *apix = (TPixel32 *)ra->getRawData(x, y);
Shinya Kitaoka 120a6e
        TPixel32 *bpix = (TPixel32 *)rb->getRawData(x, y);
Shinya Kitaoka 120a6e
        int rA         = apix->r;
Shinya Kitaoka 120a6e
        int gA         = apix->g;
Shinya Kitaoka 120a6e
        int bA         = apix->b;
Shinya Kitaoka 120a6e
        int mA         = apix->m;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        int rB = bpix->r;
Shinya Kitaoka 120a6e
        int gB = bpix->g;
Shinya Kitaoka 120a6e
        int bB = bpix->b;
Shinya Kitaoka 120a6e
        int mB = bpix->m;
Shinya Kitaoka 120a6e
        if (!areAlmostEqual(double(rA), double(rB), err) ||
Shinya Kitaoka 120a6e
            !areAlmostEqual(double(gA), double(gB), err) ||
Shinya Kitaoka 120a6e
            !areAlmostEqual(double(bA), double(bB), err) ||
Shinya Kitaoka 120a6e
            !areAlmostEqual(double(mA), double(mB), err)) {
Shinya Kitaoka 120a6e
          cout << "MISMATCH: x=" << x << " y=" << y << ". Pixel a = ("
Shinya Kitaoka 120a6e
               << (int)rA << "," << (int)gA << "," << (int)bA << "," << (int)mA
Shinya Kitaoka 120a6e
               << ")"
Shinya Kitaoka 120a6e
               << ". Pixel b = (" << (int)rB << "," << (int)gB << "," << (int)bB
Shinya Kitaoka 120a6e
               << "," << (int)mB << ")" << endl;
Shinya Kitaoka 120a6e
          return false;
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
  } else if (ra64) {
Shinya Kitaoka 120a6e
    TRaster64P rb64 = rb;
Shinya Kitaoka 120a6e
    if (!rb64) return 2;
Shinya Kitaoka 120a6e
    for (y = 0; y < ra->getLy(); y++)
Shinya Kitaoka 120a6e
      for (x = 0; x < ra->getLx(); x++) {
Shinya Kitaoka 120a6e
        TPixel64 *apix = (TPixel64 *)ra->getRawData(x, y);
Shinya Kitaoka 120a6e
        TPixel64 *bpix = (TPixel64 *)rb->getRawData(x, y);
Shinya Kitaoka 120a6e
        int rA         = apix->r;
Shinya Kitaoka 120a6e
        int gA         = apix->g;
Shinya Kitaoka 120a6e
        int bA         = apix->b;
Shinya Kitaoka 120a6e
        int mA         = apix->m;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        int rB = bpix->r;
Shinya Kitaoka 120a6e
        int gB = bpix->g;
Shinya Kitaoka 120a6e
        int bB = bpix->b;
Shinya Kitaoka 120a6e
        int mB = bpix->m;
Shinya Kitaoka 120a6e
        if (!areAlmostEqual(double(rA), double(rB), err) ||
Shinya Kitaoka 120a6e
            !areAlmostEqual(double(gA), double(gB), err) ||
Shinya Kitaoka 120a6e
            !areAlmostEqual(double(bA), double(bB), err) ||
Shinya Kitaoka 120a6e
            !areAlmostEqual(double(mA), double(mB), err)) {
Shinya Kitaoka 120a6e
          cout << "MISMATCH: x=" << x << " y=" << y << ". Pixel a = ("
Shinya Kitaoka 120a6e
               << (int)rA << "," << (int)gA << "," << (int)bA << "," << (int)mA
Shinya Kitaoka 120a6e
               << ")"
Shinya Kitaoka 120a6e
               << ". Pixel b = (" << (int)rB << "," << (int)gB << "," << (int)bB
Shinya Kitaoka 120a6e
               << "," << (int)mB << ")" << endl;
Shinya Kitaoka 120a6e
          return false;
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
  } else if (raGR8) {
Shinya Kitaoka 120a6e
    TRasterGR8P rbGR8 = rb;
Shinya Kitaoka 120a6e
    if (!rbGR8) return 2;
Shinya Kitaoka 120a6e
    for (y = 0; y < ra->getLy(); y++)
Shinya Kitaoka 120a6e
      for (x = 0; x < ra->getLx(); x++) {
Shinya Kitaoka 120a6e
        TPixelGR8 *apix = (TPixelGR8 *)ra->getRawData(x, y);
Shinya Kitaoka 120a6e
        TPixelGR8 *bpix = (TPixelGR8 *)rb->getRawData(x, y);
Shinya Kitaoka 120a6e
        int rA          = apix->value;
Shinya Kitaoka 120a6e
        int rB          = bpix->value;
Shinya Kitaoka 120a6e
        if (!areAlmostEqual(double(rA), double(rB), err)) {
Shinya Kitaoka 120a6e
          cout << "MISMATCH: x=" << x << " y=" << y << ". Pixel a = ("
Shinya Kitaoka 120a6e
               << (int)rA << ")"
Shinya Kitaoka 120a6e
               << ". Pixel b = (" << (int)rB << ")" << endl;
Shinya Kitaoka 120a6e
          return false;
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
  } else if (raCM32) {
Shinya Kitaoka 120a6e
    TRasterCM32P rbCM32 = rb;
Shinya Kitaoka 120a6e
    if (!rbCM32) return 2;
Shinya Kitaoka 120a6e
    for (y = 0; y < ra->getLy(); y++)
Shinya Kitaoka 120a6e
      for (x = 0; x < ra->getLx(); x++) {
Shinya Kitaoka 120a6e
        TPixelCM32 *apix = (TPixelCM32 *)ra->getRawData(x, y);
Shinya Kitaoka 120a6e
        TPixelCM32 *bpix = (TPixelCM32 *)rb->getRawData(x, y);
Shinya Kitaoka 120a6e
        int rAink        = apix->getInk();
Shinya Kitaoka 120a6e
        int rAtone       = apix->getTone();
Shinya Kitaoka 120a6e
        int rAPaint      = apix->getPaint();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        int rBink   = bpix->getInk();
Shinya Kitaoka 120a6e
        int rBtone  = bpix->getTone();
Shinya Kitaoka 120a6e
        int rBPaint = bpix->getPaint();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        if (!areAlmostEqual(double(rAink), double(rBink), err) ||
Shinya Kitaoka 120a6e
            !areAlmostEqual(double(rAtone), double(rBtone), err) ||
Shinya Kitaoka 120a6e
            !areAlmostEqual(double(rAPaint), double(rBPaint), err)) {
Shinya Kitaoka 120a6e
          cout << "MISMATCH: x=" << x << " y=" << y
Shinya Kitaoka 120a6e
               << ". Pixel a = (Ink: " << (int)rAink << ",Tone: " << (int)rAtone
Shinya Kitaoka 120a6e
               << ",Paint: " << (int)rBPaint << ")"
Shinya Kitaoka 120a6e
               << ". Pixel b = (Ink: " << (int)rBink << ",Tone: " << (int)rBtone
Shinya Kitaoka 120a6e
               << ",Paint: " << (int)rBPaint << ")" << endl;
Shinya Kitaoka 120a6e
          return false;
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
  } else
Shinya Kitaoka 120a6e
    return 2;
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
/*!
Toshihiro Shimizu 890ddd
*  Return true if \b va vector image and \b vb vector image are equal, with an
Toshihiro Shimizu 890ddd
*	 error less than \b err; return false otherwise.
Toshihiro Shimizu 890ddd
*  To verify vector image parity check stroke count, control point count and
Shinya Kitaoka 120a6e
*	 control point position; if vector image are different is showed an
Shinya Kitaoka 120a6e
*error message.
Toshihiro Shimizu 890ddd
*
Toshihiro Shimizu 890ddd
*  \b err max percentage variance, related to save box, allowed to control point
Toshihiro Shimizu 890ddd
*					position.
Toshihiro Shimizu 890ddd
*
Toshihiro Shimizu 890ddd
*  OSS.: Usually \b va is check image and \b vb reference image.
Toshihiro Shimizu 890ddd
*/
Shinya Kitaoka 120a6e
int areEqual(TVectorImageP va, TVectorImageP vb, double err) {
Shinya Kitaoka 120a6e
  if (!va && !vb) return true;
Shinya Kitaoka 120a6e
  int aStrokeCount = va->getStrokeCount();
Shinya Kitaoka 120a6e
  int bStrokeCount = vb->getStrokeCount();
Shinya Kitaoka 120a6e
  if (aStrokeCount != bStrokeCount) {
Shinya Kitaoka 120a6e
    cout << "MISMATCH: image stroke count = " << aStrokeCount
Shinya Kitaoka 120a6e
         << ". Reference image stroke count = " << bStrokeCount << "." << endl;
Shinya Kitaoka 120a6e
    return false;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TRectD aRect = va->getBBox();
Shinya Kitaoka 120a6e
  double lxErr = 0.00001;
Shinya Kitaoka 120a6e
  double lyErr = 0.00001;
Shinya Kitaoka 120a6e
  if (err != 0) {
Shinya Kitaoka 120a6e
    lxErr = (aRect.getLx() * err) * 0.01;
Shinya Kitaoka 120a6e
    lyErr = (aRect.getLy() * err) * 0.01;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  TRectD bRect = vb->getBBox();
Shinya Kitaoka 120a6e
  if (!areAlmostEqual(bRect.getLx(), aRect.getLx(), lxErr) ||
Shinya Kitaoka 120a6e
      !areAlmostEqual(bRect.getLy(), aRect.getLy(), lyErr)) {
Shinya Kitaoka 120a6e
    cout << "MISMATCH: different save box rect." << endl;
Shinya Kitaoka 120a6e
    return false;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int i;
Shinya Kitaoka 120a6e
  for (i = 0; i < aStrokeCount; i++) {
Shinya Kitaoka 120a6e
    TStroke *aStroke = va->getStroke(i);
Shinya Kitaoka 120a6e
    TStroke *bStroke = vb->getStroke(i);
Shinya Kitaoka 120a6e
    int aStrCPCount  = aStroke->getControlPointCount();
Shinya Kitaoka 120a6e
    int bStrCPCount  = bStroke->getControlPointCount();
Shinya Kitaoka 120a6e
    if (aStrCPCount != bStrCPCount) {
Shinya Kitaoka 120a6e
      cout << "MISMATCH: image stroke " << i
Shinya Kitaoka 120a6e
           << "_mo control point count = " << aStrCPCount
Shinya Kitaoka 120a6e
           << ". Reference image stroke " << i
Shinya Kitaoka 120a6e
           << "_mo control point count = " << bStrCPCount << "." << endl;
Shinya Kitaoka 120a6e
      return false;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    int j;
Shinya Kitaoka 120a6e
    for (j = 0; j <= aStrCPCount; j++) {
Shinya Kitaoka 120a6e
      TThickPoint aControlPoint = aStroke->getControlPoint(j);
Shinya Kitaoka 120a6e
      TThickPoint bControlPoint = bStroke->getControlPoint(j);
Shinya Kitaoka 120a6e
      if (!areAlmostEqual(aControlPoint.x, bControlPoint.x, lxErr)) {
Shinya Kitaoka 120a6e
        cout << "MISMATCH: different control point x position." << endl;
Shinya Kitaoka 120a6e
        return false;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      if (!areAlmostEqual(aControlPoint.y, bControlPoint.y, lyErr)) {
Shinya Kitaoka 120a6e
        cout << "MISMATCH: different control point y position." << endl;
Shinya Kitaoka 120a6e
        return false;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      if (!areAlmostEqual(aControlPoint.thick, bControlPoint.thick)) {
Shinya Kitaoka 120a6e
        cout << "MISMATCH: different control point thickness." << endl;
Shinya Kitaoka 120a6e
        return false;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  /* Non controllo i punti di controllo!!!
Shinya Kitaoka 120a6e
  int aStrCPCount = aStroke->getControlPointCount();
Shinya Kitaoka 120a6e
  int bStrCPCount = bStroke->getControlPointCount();
Shinya Kitaoka 120a6e
  if(aStrCPCount != bStrCPCount)
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
          cout << "MISMATCH: image stroke " << i << "_mo control point count = "
Shinya Kitaoka 120a6e
  << aStrCPCount
Shinya Kitaoka 120a6e
                           << ". Reference image stroke " << i << "_mo control
Shinya Kitaoka 120a6e
  point count = " << bStrCPCount
Shinya Kitaoka 120a6e
                           << "." << endl;
Shinya Kitaoka 120a6e
          return false;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int j;
Shinya Kitaoka 120a6e
  for(j=0; j<=aStrCPCount; j++)
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
          TThickPoint aControlPoint = aStroke->getControlPoint(j);
Shinya Kitaoka 120a6e
          TThickPoint bControlPoint = bStroke->getControlPoint(j);
Shinya Kitaoka 120a6e
          if(!areAlmostEqual(aControlPoint.x, bControlPoint.x, lxErr))
Shinya Kitaoka 120a6e
          {
Shinya Kitaoka 120a6e
                  cout << "MISMATCH: different control point x position." <<
Shinya Kitaoka 120a6e
  endl;
Shinya Kitaoka 120a6e
                  return false;
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
          if(!areAlmostEqual(aControlPoint.y, bControlPoint.y, lyErr))
Shinya Kitaoka 120a6e
          {
Shinya Kitaoka 120a6e
                  cout << "MISMATCH: different control point y position." <<
Shinya Kitaoka 120a6e
  endl;
Shinya Kitaoka 120a6e
                  return false;
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
          if(!areAlmostEqual(aControlPoint.thick, bControlPoint.thick))
Shinya Kitaoka 120a6e
          {
Shinya Kitaoka 120a6e
                  cout << "MISMATCH: different control point thickness." <<
Shinya Kitaoka 120a6e
  endl;
Shinya Kitaoka 120a6e
                  return false;
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
  }*/
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
/*!
Toshihiro Shimizu 890ddd
*  Return true if images \b a and \b b are equal, with an error
Toshihiro Shimizu 890ddd
*  less than \b err; return false otherwise.
Toshihiro Shimizu 890ddd
*
Toshihiro Shimizu 890ddd
*  If images are rasters recall
Toshihiro Shimizu 890ddd
*  \b bool areEqual(TRasterP ra, TRasterP rb)
Toshihiro Shimizu 890ddd
*  else if image are vectorImage recall
Toshihiro Shimizu 890ddd
*  \b bool areEqual(TVectorImageP ra, TVectorImageP rb)
Toshihiro Shimizu 890ddd
*/
Shinya Kitaoka 120a6e
int areEqual(TImageP a, TImageP b, double err) {
Shinya Kitaoka 120a6e
  if (!a && !b) return true;
Shinya Kitaoka 120a6e
  if (!a || !b) return false;
Shinya Kitaoka 120a6e
  if (a->getType() != b->getType()) return false;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TRasterImageP ra(a);
Shinya Kitaoka 120a6e
  TRasterImageP rb(b);
Shinya Kitaoka 120a6e
  if ((!ra && rb) || (ra && !rb)) return false;
Shinya Kitaoka 120a6e
  if (ra && rb) return areEqual(ra->getRaster(), rb->getRaster(), err);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TToonzImageP ta(a);
Shinya Kitaoka 120a6e
  TToonzImageP tb(b);
Shinya Kitaoka 120a6e
  if ((!ta && tb) || (ta && !tb)) return false;
Shinya Kitaoka 120a6e
  if (ta && tb) return areEqual(ta->getRaster(), tb->getRaster(), err);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TVectorImageP va(a);
Shinya Kitaoka 120a6e
  TVectorImageP vb(b);
Shinya Kitaoka 120a6e
  if (va && vb) return areEqual(va, vb, err);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool areEqual(const TPalette *paletteA, const TPalette *paletteB) {
Shinya Kitaoka 120a6e
  if (paletteA->getStyleCount() != paletteB->getStyleCount() ||
Shinya Kitaoka 120a6e
      paletteA->getPageCount() != paletteB->getPageCount()) {
Shinya Kitaoka 120a6e
    cout << "PALETTE style count MISMATCH" << endl;
Shinya Kitaoka 120a6e
    return false;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  int i;
Shinya Kitaoka 120a6e
  for (i = 0; i < paletteA->getStyleCount(); i++) {
Shinya Kitaoka 120a6e
    TColorStyle *styleA = paletteA->getStyle(i);
Shinya Kitaoka 120a6e
    TColorStyle *styleB = paletteB->getStyle(i);
Shinya Kitaoka 120a6e
    if (styleA->getMainColor() == styleB->getMainColor()) continue;
Shinya Kitaoka 120a6e
    cout << "PALETTE style MISMATCH" << endl;
Shinya Kitaoka 120a6e
    return false;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool areEqual(TLevelP la, TLevelP lb) {
Shinya Kitaoka 120a6e
  if (la->getFrameCount() != lb->getFrameCount()) {
Shinya Kitaoka 120a6e
    cout << "FRAME COUNT MISMATCH" << endl;
Shinya Kitaoka 120a6e
    return false;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (!areEqual(la->getPalette(), lb->getPalette())) return false;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TLevel::Iterator ait = la->begin(), bit = lb->begin();
Shinya Kitaoka 120a6e
  for (; ait != la->end(); ait++, bit++) {
Shinya Kitaoka 120a6e
    assert(bit != lb->end());
Shinya Kitaoka 120a6e
    if (!areEqual(ait->second, bit->second)) return false;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}